f716d5b05d
Recent kernel change means that if gssd isn't running and NFSv4 mount will wait 15 seconds before timing out even if gss security wasn't requested. So just start gssd alway - there is no significant cost in this. (bnc#837262) OBS-URL: https://build.opensuse.org/package/show/Base:System/nfs-utils?expand=0&rev=94
386 lines
9.2 KiB
Bash
386 lines
9.2 KiB
Bash
#! /bin/bash
|
|
# Copyright (c) 1996-2002 SuSE Linux AG, Nuernberg, Germany.
|
|
# Copyright (c) 2008 SuSE LINUX Products GmbH, Nuernberg, Germany.
|
|
# All rights reserved.
|
|
#
|
|
# Author: Florian La Roche, 1996
|
|
# Werner Fink <werner@suse.de>, 1996,2008
|
|
# 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: $network $portmap
|
|
# Default-Start: 3 5
|
|
# Default-Stop: 0 1 2 6
|
|
# Short-Description: NFS client services
|
|
# Description: All necessary services for NFS clients
|
|
### END INIT INFO
|
|
|
|
. /etc/rc.status
|
|
. /etc/sysconfig/nfs
|
|
|
|
# XXX: there should be separate init scripts for these really
|
|
IDMAPD_BIN=/usr/sbin/rpc.idmapd
|
|
GSSD_BIN=/usr/sbin/rpc.gssd
|
|
STATD_BIN=/usr/sbin/rpc.statd
|
|
|
|
IDMAPD_CLIENT_STATE=/run/nfs/nfs-rpc.idmapd
|
|
IDMAPD_SERVER_STATE=/run/nfs/nfsserver-rpc.idmapd
|
|
|
|
if [ -z "$RPC_PIPEFS_DIR" ]; then
|
|
RPC_PIPEFS_DIR=/var/lib/nfs/rpc_pipefs
|
|
fi
|
|
|
|
NEED_IDMAPD=no
|
|
#always start gssd, else kernel waits for it.
|
|
NEED_GSSD=yes
|
|
NEED_LDCONFIG=no
|
|
state=0
|
|
usr=""
|
|
opt=""
|
|
mnt=""
|
|
nfs=$NFS_START_SERVICES
|
|
if [ "x$nfs" != "xyes" ]
|
|
then nfs=no
|
|
fi
|
|
|
|
while read -r what where type options rest ; do
|
|
case "$what" in
|
|
\#*|"") continue ;;
|
|
esac
|
|
case ",$options," in
|
|
*,noauto,*) continue ;;
|
|
esac
|
|
case "$type" in
|
|
nfs|nfs4) ;;
|
|
*) continue ;;
|
|
esac
|
|
nfs=yes
|
|
if test "$1" = status ; then
|
|
grep -qF "$what $where nfs
|
|
$what/ $where nfs" /proc/mounts && continue
|
|
state=3
|
|
continue
|
|
fi
|
|
case "$where" in
|
|
/usr*)
|
|
usr="${usr:+$usr }$where"
|
|
NEED_LDCONFIG=yes
|
|
;;
|
|
/opt*)
|
|
opt="${opt:+$opt }$where"
|
|
NEED_LDCONFIG=yes
|
|
;;
|
|
*)
|
|
mnt="${mnt:+$mnt }$where"
|
|
test "$NEED_LDCONFIG" = yes && continue
|
|
grep -qE "^$where" /etc/ld.so.conf || continue
|
|
NEED_LDCONFIG=yes
|
|
;;
|
|
esac
|
|
done < /etc/fstab
|
|
unset what where type options rest
|
|
|
|
case $NFS_SECURITY_GSS in
|
|
[Nn]*) flavors="";;
|
|
[Yy]*) flavors=krb5;;
|
|
*) flavors="$NFS_SECURITY_GSS";;
|
|
esac
|
|
|
|
if test -n "$flavors" ; then
|
|
NEED_GSSD=yes
|
|
fi
|
|
if test -n "$GSSD_OPTIONS"; then
|
|
NEED_GSSD=yes
|
|
fi
|
|
|
|
case $NFS_GSSD_AVOID_DNS in
|
|
[Nn]*) ignore_dns=-D ;;
|
|
[Yy]*) ignore_dns= ;;
|
|
* ) ignore_dns=-D
|
|
esac
|
|
|
|
if test "$NFS4_SUPPORT" = yes ; then
|
|
NEED_IDMAPD=yes
|
|
fi
|
|
if grep -E '^(sunrpc|fs.nfs)' /etc/sysctl.conf > /dev/null 2>&1 ; then
|
|
nfs=yes
|
|
fi
|
|
|
|
check_portmap() {
|
|
# check if either portmap or rpcbind is running
|
|
if test -x /sbin/portmap && checkproc /sbin/portmap
|
|
then true
|
|
elif test -x /sbin/rpcbind && checkproc /sbin/rpcbind
|
|
then true
|
|
else false
|
|
fi
|
|
}
|
|
|
|
if ! test "$nfs" = no -o -x /sbin/portmap -o -x /sbin/rpcbind; then
|
|
echo "portmap/rpcbind is missing"
|
|
rc_failed 3
|
|
rc_status -v
|
|
rc_exit
|
|
fi
|
|
|
|
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() {
|
|
# See if the file system is there
|
|
case `stat -c "%t" -f "$RPC_PIPEFS_DIR"` in
|
|
*67596969*)
|
|
umount "$RPC_PIPEFS_DIR"
|
|
esac
|
|
}
|
|
|
|
mount_usr() {
|
|
test -n "$usr" -o -n "$opt" || return
|
|
local where
|
|
for where in $usr $opt ; do
|
|
mount -o nolock $where || {
|
|
# maybe network device hasn't appeared yet.
|
|
udevadm settle
|
|
mount -o nolock $where
|
|
}
|
|
done
|
|
}
|
|
|
|
do_start_gssd() {
|
|
for flavor in $flavors; do
|
|
/sbin/modprobe rpcsec_gss_$flavor
|
|
done
|
|
mount_rpc_pipefs
|
|
startproc $GSSD_BIN $ignore_dns $GSSD_OPTIONS
|
|
return $?
|
|
}
|
|
|
|
do_start_idmapd() {
|
|
mount_rpc_pipefs
|
|
|
|
# as idmapd needs to be run by 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
|
|
return $?
|
|
fi
|
|
}
|
|
|
|
rc_reset
|
|
case "$1-$nfs" in
|
|
start-no|reload-no)
|
|
# Always run smnotify, even if no mounts are listed in fstab.
|
|
# If there is nothing to do, it will exit quickly, and if there
|
|
# is something to do, the sooner it is done, the better.
|
|
/usr/sbin/sm-notify $SM_NOTIFY_OPTIONS
|
|
echo -n "Not starting NFS client services - no NFS found in /etc/fstab:"
|
|
rc_status -u
|
|
;;
|
|
start-yes|force-start-*)
|
|
echo -n "Starting NFS client services:"
|
|
if ! check_portmap ; then
|
|
echo "portmap/rpcbind is not running"
|
|
rc_failed 3
|
|
rc_status -v
|
|
rc_exit
|
|
fi
|
|
|
|
# explicit modprobe so we can set some sysctl values
|
|
# before any daemons (e.g. lockd) start.
|
|
# When modprobe allows this to be moved to modprobe.d
|
|
# without breaking --show-depends, this can be removed.
|
|
modprobe nfs
|
|
grep -E '^(sunrpc|fs.nfs)' /etc/sysctl.conf | sysctl -q -e -n -p -
|
|
|
|
# in case we need /usr and/or /opt via nfs
|
|
mount_usr
|
|
|
|
# sm-notify
|
|
echo -n " sm-notify"
|
|
/usr/sbin/sm-notify $SM_NOTIFY_OPTIONS
|
|
|
|
# start gssd
|
|
if test "$NEED_GSSD" = yes ; then
|
|
echo -n " gssd"
|
|
do_start_gssd || {
|
|
rc_status -v
|
|
rc_exit
|
|
}
|
|
fi
|
|
|
|
# start idmapd
|
|
if test "$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_CLIENT_STATE
|
|
fi
|
|
|
|
rc_status -v
|
|
# remark: statd is started when needed by mount.nfs
|
|
|
|
# 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
|
|
#
|
|
if test -n "$mnt" ; then
|
|
# If network devices are not yet discovered, mounts
|
|
# might fail, so we might need to 'udevadm settle' to
|
|
# wait for the interfaces.
|
|
# We cannot try the mount and on failure: 'settle' and try again
|
|
# as if there are 'bg' mounts, we could get multiple copies
|
|
# of them. So always 'settle' if there is any mounting to do.
|
|
echo -n "Mounting network file systems ..."
|
|
udevadm settle
|
|
mount -at nfs,nfs4 || rc_failed 1
|
|
rc_status -v
|
|
fi
|
|
#
|
|
# generate new list of available shared libraries
|
|
#
|
|
if test "$NEED_LDCONFIG" = yes; then
|
|
# check if ld.so.cache needs to be refreshed
|
|
/etc/init.d/boot.ldconfig start
|
|
fi
|
|
#
|
|
;;
|
|
stop* )
|
|
echo -n "Shutting down NFS client services:"
|
|
|
|
rootfs=`awk '$2 == "/" && $1 != "rootfs" {print $3}' /proc/mounts`
|
|
|
|
if test x$rootfs = xnfs ; then
|
|
echo -n " root filesystem is on NFS"
|
|
rc_status -s
|
|
else
|
|
# kill process to maximise chance that umount succeeds
|
|
mnt=`awk '$3 ~ /^nfs4*$/ {print $2}' /proc/mounts`
|
|
runlevel=`runlevel | awk '{print $2}'`
|
|
if test "$runlevel" -eq 0 -o "$runlevel" -eq 6; then
|
|
if test -n "$mnt" ; then
|
|
/sbin/mkill -TERM $mnt
|
|
fi
|
|
fi
|
|
|
|
# if filesystems are not busy, wait for unmount to complete..
|
|
umount -at nfs,nfs4
|
|
# if they are still busy, do a lazy unmount anyway.
|
|
umount -alt nfs,nfs4
|
|
|
|
# stop gssd
|
|
if checkproc $GSSD_BIN; then
|
|
echo -n " gssd"
|
|
killproc $GSSD_BIN
|
|
fi
|
|
|
|
# stop idmapd
|
|
if test -f $IDMAPD_CLIENT_STATE; then
|
|
# only stop idmapd if it is not needed by server
|
|
if test ! -f $IDMAPD_SERVER_STATE ; then
|
|
echo -n " idmapd"
|
|
killproc $IDMAPD_BIN
|
|
fi
|
|
rm -f $IDMAPD_CLIENT_STATE
|
|
fi
|
|
|
|
# stop rpc.statd if not needed by server
|
|
if checkproc $STATD_BIN ; then
|
|
if [ `cat /proc/fs/nfsd/threads 2> /dev/null`0 -eq 0 ]; then
|
|
echo -n " rpc.statd"
|
|
killproc $STATD_BIN
|
|
fi
|
|
fi
|
|
|
|
umount_rpc_pipefs
|
|
|
|
rc_status -v
|
|
fi
|
|
;;
|
|
reload*|force-reload*)
|
|
# only IDMAP has any sense in which 'reload' makes sense.
|
|
if checkproc $IDMAPD_BIN; then
|
|
killproc -HUP $IDMAPD_BIN
|
|
fi
|
|
rc_status
|
|
;;
|
|
restart*)
|
|
## Stop the service and regardless of whether it was
|
|
## running or not, start it again.
|
|
$0 stop
|
|
$0 force-start
|
|
rc_status
|
|
;;
|
|
status*)
|
|
echo -n "Checking for mounted nfs shares (from /etc/fstab):"
|
|
if test "$nfs" = yes ; then
|
|
rc_failed $state
|
|
else
|
|
rc_failed 3
|
|
fi
|
|
#
|
|
if test "$NEED_GSSD" = yes && ! checkproc $GSSD_BIN; then
|
|
echo "gssd not running"
|
|
rc_failed 3
|
|
fi
|
|
#
|
|
if test "$NEED_IDMAPD" = yes && ! checkproc $IDMAPD_BIN; then
|
|
echo "idmapd not running"
|
|
rc_failed 3
|
|
fi
|
|
if ! check_portmap; then
|
|
echo "Warning: portmap/rpcbind not running - nfs may not work well"
|
|
fi
|
|
rc_status -v
|
|
;;
|
|
try-restart*|condrestart*)
|
|
# This restart is not only conditional on the services already
|
|
# running, but is also gentler in that NFS filesystems are
|
|
# not unmounted or remounted.
|
|
# It is possible that the programs have been reinstalled so
|
|
# we pass a basename rather than a full path to checkproc and killproc
|
|
echo -n "Restarting NFS services:"
|
|
if checkproc ${GSSD_BIN##*/}; then
|
|
echo -n " gssd"
|
|
killproc ${GSSD_BIN##*/}
|
|
startproc $GSSD_BIN $ignore_dns $GSSD_OPTIONS
|
|
fi
|
|
if checkproc ${IDMAPD_BIN##*/}; then
|
|
echo -n " idmapd"
|
|
killproc ${IDMAPD_BIN##*/}
|
|
startproc $IDMAPD_BIN
|
|
fi
|
|
if checkproc ${STATD_BIN##*/}; then
|
|
echo -n " statd"
|
|
killproc ${STATD_BIN##*/}
|
|
/usr/sbin/start-statd
|
|
fi
|
|
rc_status -v
|
|
;;
|
|
*)
|
|
echo "Usage: $0 {start|stop|status|reload|force-reload|restart|try-restart}"
|
|
exit 1
|
|
esac
|
|
rc_exit
|