cc1abc1879
If a path name has a space, it will appear as \040 in fstab and in /proc/mounts. Using 'grep -E' to search for this is problematic as it will interpret the '\'. So use 'grep -F' instead - we know there is only a single space in /proc/mounts. Also use "read -r" so 'read' doesn't interpret the '/'. (bnc#666128) OBS-URL: https://build.opensuse.org/package/show/Base:System/nfs-utils?expand=0&rev=39
369 lines
8.8 KiB
Bash
369 lines
8.8 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
|
|
|
|
IDMAPD_BIN=/usr/sbin/rpc.idmapd
|
|
GSSD_BIN=/usr/sbin/rpc.gssd
|
|
STATD_BIN=/usr/sbin/rpc.statd
|
|
|
|
IDMAPD_CLIENT_STATE=/var/lock/subsys/nfs-rpc.idmapd
|
|
IDMAPD_SERVER_STATE=/var/lock/subsys/nfsserver-rpc.idmapd
|
|
|
|
NEED_IDMAPD=no
|
|
NEED_GSSD=no
|
|
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" /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 "$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 /var/lib/nfs/rpc_pipefs` in
|
|
*67596969*)
|
|
return 0;;
|
|
esac
|
|
mount -t rpc_pipefs rpc_pipefs /var/lib/nfs/rpc_pipefs
|
|
}
|
|
|
|
umount_rpc_pipefs() {
|
|
# See if the file system is there
|
|
case `stat -c "%t" -f /var/lib/nfs/rpc_pipefs` in
|
|
*67596969*)
|
|
umount /var/lib/nfs/rpc_pipefs
|
|
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
|
|
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
|
|
}
|
|
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
|
|
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
|