2015-06-24 14:36:14 +03:00
#!/bin/sh
# Exit on 1st error
set -e
2015-09-02 02:38:04 +03:00
# NFS exports file. Some code below keeps a cache of output derived
# from exportfs(8). When this file is updated the cache is invalid
# and needs to be regenerated.
#
# To change the file, edit the default value below. Do not set
# CTDB_NFS_EXPORTS_FILE - it isn't a configuration variable, just a
# hook for testing.
nfs_exports_file="${CTDB_NFS_EXPORTS_FILE:-/var/lib/nfs/etab}"
2019-03-26 06:49:49 +03:00
# As above, edit the default value below. CTDB_NFS_DISTRO_STYLE is a
# test variable only.
2019-03-26 07:05:58 +03:00
nfs_distro_style="${CTDB_NFS_DISTRO_STYLE:-systemd-redhat}"
2019-03-26 06:49:49 +03:00
case "$nfs_distro_style" in
2019-03-20 09:45:10 +03:00
systemd-*)
# Defaults
nfs_service="nfs-server"
nfs_lock_service="rpc-statd"
nfs_mountd_service="nfs-mountd"
nfs_status_service="rpc-statd"
nfs_rquotad_service="rpc-rquotad"
nfs_config="/etc/sysconfig/nfs"
nfs_rquotad_config="" # Not use with systemd, restart via service
case "$nfs_distro_style" in
*-redhat|*-suse)
: # Defaults only
;;
*-debian)
nfs_rquotad_service="quotarpc"
;;
*)
echo "Internal error"
exit 1
esac
;;
2019-03-26 06:49:49 +03:00
sysvinit-*)
# Defaults
nfs_service="nfs"
nfs_lock_service=""
2019-03-20 09:35:44 +03:00
nfs_mountd_service=""
nfs_status_service=""
nfs_rquotad_service=""
2019-03-26 06:49:49 +03:00
nfs_config="/etc/sysconfig/nfs"
2019-03-20 09:35:44 +03:00
nfs_rquotad_config="$nfs_config"
2019-03-26 06:49:49 +03:00
case "$nfs_distro_style" in
*-redhat)
nfs_lock_service="nfslock"
;;
*-suse)
nfs_service="nfsserver"
;;
*-debian)
nfs_service="nfs-kernel-server"
nfs_config="/etc/default/nfs-kernel-server"
2019-03-20 09:35:44 +03:00
nfs_rquotad_config="/etc/default/quota"
2019-03-26 06:49:49 +03:00
;;
*)
echo "Internal error"
exit 1
esac
;;
*)
echo "Internal error"
exit 1
esac
2015-06-24 14:36:14 +03:00
# Override for unit testing
if [ -z "$PROCFS_PATH" ] ; then
PROCFS_PATH="/proc"
fi
##################################################
usage ()
{
2016-06-29 11:11:44 +03:00
_c=$(basename "$0")
2015-06-24 14:36:14 +03:00
cat <<EOF
usage: $_c { shutdown | startup }
$_c { stop | start } { nfs | nlockmgr }
$_c { monitor-list-shares | monitor-post }
2015-07-14 05:11:39 +03:00
$_c { register }
2015-06-24 14:36:14 +03:00
EOF
exit 1
}
2019-03-20 08:11:32 +03:00
##################################################
nfs_load_config ()
{
_config="${1:-${nfs_config}}"
if [ -r "$_config" ] ; then
. "$_config"
fi
}
2015-06-24 14:36:14 +03:00
##################################################
# Basic service stop and start
basic_stop ()
{
2019-03-18 06:42:36 +03:00
case "$1" in
2015-06-24 14:36:14 +03:00
nfs)
2019-03-21 07:30:00 +03:00
if [ -n "$nfs_rquotad_service" ] ; then
service "$nfs_rquotad_service" stop
fi
2015-06-24 14:36:14 +03:00
service "$nfs_service" stop
2019-03-21 07:30:00 +03:00
2019-03-20 06:50:59 +03:00
if [ -n "$nfs_lock_service" ] ; then
service "$nfs_lock_service" stop
2019-03-18 06:42:36 +03:00
fi
;;
nfslock)
2019-03-20 06:50:59 +03:00
if [ -n "$nfs_lock_service" ] ; then
service "$nfs_lock_service" stop
2019-03-18 06:42:36 +03:00
else
service "$nfs_service" stop
fi
;;
2015-06-24 14:36:14 +03:00
*)
2019-03-18 06:42:36 +03:00
usage
esac
2015-06-24 14:36:14 +03:00
}
basic_start ()
{
2019-03-18 06:42:36 +03:00
case "$1" in
2015-06-24 14:36:14 +03:00
nfs)
2019-03-20 06:50:59 +03:00
if [ -n "$nfs_lock_service" ] ; then
service "$nfs_lock_service" start
2019-03-18 06:42:36 +03:00
fi
2019-03-21 07:30:00 +03:00
2015-06-24 14:36:14 +03:00
service "$nfs_service" start
2019-03-21 07:30:00 +03:00
if [ -n "$nfs_rquotad_service" ] ; then
service "$nfs_rquotad_service" start
fi
2019-03-18 06:42:36 +03:00
;;
nfslock)
2019-03-20 06:50:59 +03:00
if [ -n "$nfs_lock_service" ] ; then
service "$nfs_lock_service" start
2019-03-18 06:42:36 +03:00
else
service "$nfs_service" start
fi
;;
2015-06-24 14:36:14 +03:00
*)
2019-03-18 06:42:36 +03:00
usage
esac
2015-06-24 14:36:14 +03:00
}
##################################################
# service "stop" and "start" options for restarting
service_stop ()
{
2019-03-18 06:42:36 +03:00
case "$1" in
2015-06-24 14:36:14 +03:00
nfs)
2019-03-18 06:42:36 +03:00
echo 0 >"${PROCFS_PATH}/fs/nfsd/threads"
basic_stop "nfs" >/dev/null 2>&1 || true
pkill -9 nfsd
;;
2015-06-24 14:36:14 +03:00
nlockmgr)
2019-03-18 06:42:36 +03:00
basic_stop "nfslock" >/dev/null 2>&1 || true
;;
2019-03-20 09:35:44 +03:00
mountd)
if [ -n "$nfs_mountd_service" ] ; then
service "$nfs_mountd_service" stop
return
fi
# Default to stopping by hand
killall -q -9 rpc.mountd
;;
rquotad)
if [ -n "$nfs_rquotad_service" ] ; then
service "$nfs_rquotad_service" stop
return
fi
# Default to stopping by hand
killall -q -9 rpc.rquotad
;;
status)
if [ -n "$nfs_status_service" ] ; then
service "$nfs_status_service" stop
return
fi
# Default to stopping by hand
killall -q -9 rpc.statd
;;
2015-06-24 14:36:14 +03:00
*)
2019-03-18 06:42:36 +03:00
usage
esac
2015-06-24 14:36:14 +03:00
}
service_start ()
{
2019-03-18 06:42:36 +03:00
case "$1" in
2015-06-24 14:36:14 +03:00
nfs)
2019-03-18 06:42:36 +03:00
basic_start "nfs"
;;
2015-06-24 14:36:14 +03:00
nlockmgr)
2019-03-18 06:42:36 +03:00
basic_start "nfslock"
;;
2019-03-20 09:35:44 +03:00
mountd)
if [ -n "$nfs_mountd_service" ] ; then
service "$nfs_mountd_service" start
return
fi
# Default to starting by hand
nfs_load_config
if [ -z "$RPCMOUNTDOPTS" ] ; then
RPCMOUNTDOPTS="${MOUNTD_PORT:+-p }$MOUNTD_PORT"
fi
# shellcheck disable=SC2086
rpc.mountd $RPCMOUNTDOPTS
;;
rquotad)
if [ -n "$nfs_rquotad_service" ] ; then
service "$nfs_rquotad_service" start
return
fi
# Default to starting by hand
nfs_load_config "$nfs_rquotad_config"
if [ -z "$RPCRQUOTADOPTS" ] ; then
RPCRQUOTADOPTS="${RQUOTAD_PORT:+-p }$RQUOTAD_PORT"
fi
# shellcheck disable=SC2086
rpc.rquotad $RPCRQUOTADOPTS
;;
status)
if [ -n "$nfs_status_service" ] ; then
service "$nfs_status_service" start
return
fi
# Default to starting by hand
nfs_load_config
# Red Hat uses STATDARG, Debian uses STATDOPTS
opts="${STATDARG:-${STATDOPTS:-''}}"
if [ -z "$opts" ] ; then
# shellcheck disable=SC2086
set -- \
${STATD_HA_CALLOUT:+-H} $STATD_HA_CALLOUT \
${STATD_HOSTNAME:+-n} $STATD_HOSTNAME \
${STATD_PORT:+-p} $STATD_PORT \
${STATD_OUTGOING_PORT:+-o} $STATD_OUTGOING_PORT
opts="$*"
fi
# shellcheck disable=SC2086
rpc.statd $opts
;;
2015-06-24 14:36:14 +03:00
*)
2019-03-18 06:42:36 +03:00
usage
esac
2015-06-24 14:36:14 +03:00
}
##################################################
# service init startup and final shutdown
nfs_shutdown ()
{
basic_stop "nfs"
}
nfs_startup ()
{
basic_stop "nfs" || true
basic_start "nfs"
_f="${PROCFS_PATH}/sys/net/ipv4/tcp_tw_recycle"
2019-06-03 05:44:15 +03:00
if [ -f "$_f" ] ; then
echo 1 >"$_f"
2015-06-24 14:36:14 +03:00
fi
}
##################################################
# monitor-post support
nfs_check_thread_count ()
{
# Load NFS configuration to get desired number of threads.
2019-03-20 08:11:32 +03:00
nfs_load_config
2015-06-24 14:36:14 +03:00
# If $RPCNFSDCOUNT/$USE_KERNEL_NFSD_NUMBER isn't set then we could
# guess the default from the initscript. However, let's just
# assume that those using the default don't care about the number
# of threads and that they have switched on this feature in error.
_configured_threads="${RPCNFSDCOUNT:-${USE_KERNEL_NFSD_NUMBER}}"
2020-07-20 05:02:45 +03:00
if [ -z "$_configured_threads" ] && type nfsconf >/dev/null 2>&1 ; then
_configured_threads=$(nfsconf --get nfsd threads) || true
fi
2015-06-24 14:36:14 +03:00
[ -n "$_configured_threads" ] || return 0
_threads_file="${PROCFS_PATH}/fs/nfsd/threads"
# nfsd should be running the configured number of threads. If
# there are a different number of threads then tell nfsd the
# correct number.
2016-03-10 01:12:33 +03:00
read _running_threads <"$_threads_file" || {
echo "WARNING: Reading \"${_threads_file}\" unexpectedly failed"
exit 0
}
2015-06-24 14:36:14 +03:00
# Intentionally not arithmetic comparison - avoids extra errors
2016-03-10 01:12:33 +03:00
# when above read fails in an unexpected way...
2019-04-04 10:21:49 +03:00
if [ "$_running_threads" != "$_configured_threads" ] ; then
echo "Attempting to correct number of nfsd threads from ${_running_threads} to ${_configured_threads}"
2015-06-24 14:36:14 +03:00
echo "$_configured_threads" >"$_threads_file"
fi
}
##################################################
# list share directories
nfs_monitor_list_shares ()
{
2015-09-02 02:38:04 +03:00
_cache_file="${CTDB_NFS_CALLOUT_STATE_DIR}/list_shares_cache"
2016-07-12 04:57:55 +03:00
# -nt operator is well supported in Linux: dash, bash, ksh, ...
2021-06-21 13:30:21 +03:00
# shellcheck disable=SC2039,SC3013
2015-09-02 02:38:04 +03:00
if [ ! -r "$nfs_exports_file" ] || [ ! -r "$_cache_file" ] || \
[ "$nfs_exports_file" -nt "$_cache_file" ] ; then
mkdir -p "$CTDB_NFS_CALLOUT_STATE_DIR"
# We could just use the contents of $nfs_exports_file.
# However, let's regard that file as internal to NFS and use
# exportfs, which is the public API.
if ! _exports=$(exportfs -v) ; then
echo "WARNING: failed to run exportfs to list NFS shares" >&2
return
fi
echo "$_exports" |
grep '^/' |
sed -e 's@[[:space:]][[:space:]]*[^[:space:]()][^[:space:]()]*([^[:space:]()][^[:space:]()]*)$@@' |
sort -u >"$_cache_file"
fi
cat "$_cache_file"
2015-06-24 14:36:14 +03:00
}
##################################################
2015-07-14 05:13:58 +03:00
nfs_register ()
{
cat <<EOF
shutdown
startup
stop
start
monitor-list-shares
monitor-post
EOF
}
##################################################
2015-06-24 14:36:14 +03:00
case "$1" in
shutdown)
nfs_shutdown
;;
startup)
nfs_startup
;;
stop)
service_stop "$2"
;;
start)
service_start "$2"
;;
monitor-list-shares)
nfs_monitor_list_shares
;;
monitor-post)
nfs_check_thread_count
;;
2015-07-14 05:11:39 +03:00
register)
2015-07-14 05:13:58 +03:00
nfs_register
2015-07-14 05:11:39 +03:00
;;
2016-06-06 07:03:47 +03:00
monitor-pre|releaseip|takeip|releaseip-pre|takeip-pre)
2015-06-24 14:36:14 +03:00
# Not required/implemented
:
;;
*)
usage
esac