nfs-utils/nfsserver.init
Neil Brown 5851cf522d - nfsserver.init: make sure sm-notify runs on restart.
If we stop nfsd, that might also stop lockd which would
  drop locks.  So make sure lockd really does drop lock
  for consistency, and ensure that sm-notify is run when
  nfsserver is restarted. (bnc#668280)

OBS-URL: https://build.opensuse.org/package/show/Base:System/nfs-utils?expand=0&rev=38
2011-02-16 23:51:28 +00:00

355 lines
9.0 KiB
Bash

#! /bin/sh
# Copyright (c) 1996 - 2007 SuSE GmbH Nuernberg, Germany. All rights reserved.
#
# Author: Florian La Roche <florian@suse.de>, 1996
# Werner Fink <werner@suse.de>, 1996,98
# Burchard Steinbild <bs@suse.de>, 1997
# Thorsten Kukuk <kukuk@suse.de>, 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 <num> set local and overall rc status to <num><num>
# 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.
SVCGSSD_BIN=/usr/sbin/rpc.svcgssd
IDMAPD_BIN=/usr/sbin/rpc.idmapd
NFSD_BIN=/usr/sbin/rpc.nfsd
IDMAPD_CLIENT_STATE=/var/lock/subsys/nfs-rpc.idmapd
IDMAPD_SERVER_STATE=/var/lock/subsys/nfsserver-rpc.idmapd
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
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() {
# 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
test -d "$export" || mkdir -p "$export"
# Fortunately, mount ignores unknown
# options, so we have an easy way to
# tag our "magic" bind mounts
mount -o bind,nfsexp "$dir" "$export"
done
}
nfs4_unbind_mounts() {
cat /etc/mtab |
grep '\<nfsexp\>' |
sort -r -k2 |
while read src mountpoint crap; do
umount -l "$mountpoint"
done
}
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() {
case `stat -c "%t" -f /var/lib/nfs/rpc_pipefs` in
*67596969*)
umount /var/lib/nfs/rpc_pipefs;;
esac
}
do_start_svcgssd() {
for flavor in $flavors; do
/sbin/modprobe rpcsec_gss_$flavor
done
mount_rpc_pipefs
startproc $SVCGSSD_BIN
return $?
}
do_start_idmapd() {
mount_rpc_pipefs
if checkproc $IDMAPD_BIN && test -f $IDMAPD_CLIENT_STATE; then
killproc -HUP $IDMAPD_BIN
else
startproc $IDMAPD_BIN
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_LIST="+2 +3 "
else
VERSION_LIST="-2 -3"
VERSION_PARAMS="--no-nfs-version 2 --no-nfs-version 3"
fi
if [ "$NFS4_SUPPORT" = "yes" ]; then
VERSION_LIST="$VERSION_LIST +4"
else
VERSION_LIST="$VERSION_LIST -4"
VERSION_PARAMS="--no-nfs-version 4"
fi
if [ " `cat /proc/fs/nfsd/threads`" = " 0" ]; then
echo $VERSION_LIST > /proc/fs/nfsd/versions
fi
nfs4_bind_mounts
# svcgssd; idmapd
if [ "$NEED_SVCGSSD" = yes ]; then
echo -n " svcgssd"
do_start_svcgssd || {
rc_status -v
rc_exit
}
fi
if [ "$NEED_IDMAPD" = yes ]; then
echo -n " idmapd"
do_start_idmapd || {
rc_status -v
rc_exit
}
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 $VERSION_PARAMS
else
startproc /usr/sbin/rpc.mountd $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 $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 /var/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
}
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 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 /var/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
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