mirror of
https://github.com/samba-team/samba.git
synced 2025-02-14 01:57:53 +03:00
exportfs can hang when, for example, DNS is flakey. Given that exports don't change much, it makes sense to cache them. Don't try to add error handling when exportfs fails but do print a warning. Proper error handling can be added separately. Signed-off-by: Martin Schwenke <martin@meltin.net> Reviewed-by: Amitay Isaacs <amitay@gmail.com>
248 lines
5.1 KiB
Bash
Executable File
248 lines
5.1 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
# Exit on 1st error
|
|
set -e
|
|
|
|
# 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}"
|
|
|
|
# Red Hat
|
|
nfs_service="nfs"
|
|
nfslock_service="nfslock"
|
|
nfs_config="/etc/sysconfig/nfs"
|
|
|
|
# SUSE
|
|
#nfs_service="nfsserver"
|
|
#nfslock_service=""
|
|
#nfs_config="/etc/sysconfig/nfs"
|
|
|
|
# Debian
|
|
#nfs_service="nfs-kernel-server"
|
|
#nfslock_service=""
|
|
#nfs_config="/etc/default/nfs-kernel-server"
|
|
|
|
# Override for unit testing
|
|
if [ -z "$PROCFS_PATH" ] ; then
|
|
PROCFS_PATH="/proc"
|
|
fi
|
|
|
|
##################################################
|
|
|
|
usage ()
|
|
{
|
|
_c=$(basename $0)
|
|
cat <<EOF
|
|
usage: $_c { shutdown | startup }
|
|
$_c { stop | start } { nfs | nlockmgr }
|
|
$_c { monitor-list-shares | monitor-post }
|
|
$_c { register }
|
|
EOF
|
|
exit 1
|
|
}
|
|
|
|
|
|
##################################################
|
|
# Basic service stop and start
|
|
|
|
basic_stop ()
|
|
{
|
|
case "$1" in
|
|
nfs)
|
|
service "$nfs_service" stop
|
|
if [ -n "$nfslock_service" ] ; then
|
|
service "$nfslock_service" stop
|
|
fi
|
|
;;
|
|
nfslock)
|
|
if [ -n "$nfslock_service" ] ; then
|
|
service "$nfslock_service" stop
|
|
else
|
|
service "$nfs_service" stop
|
|
fi
|
|
;;
|
|
*)
|
|
usage
|
|
esac
|
|
}
|
|
|
|
basic_start ()
|
|
{
|
|
case "$1" in
|
|
nfs)
|
|
if [ -n "$nfslock_service" ] ; then
|
|
service "$nfslock_service" start
|
|
fi
|
|
service "$nfs_service" start
|
|
;;
|
|
nfslock)
|
|
if [ -n "$nfslock_service" ] ; then
|
|
service "$nfslock_service" start
|
|
else
|
|
service "$nfs_service" start
|
|
fi
|
|
;;
|
|
*)
|
|
usage
|
|
esac
|
|
}
|
|
|
|
##################################################
|
|
# service "stop" and "start" options for restarting
|
|
|
|
service_stop ()
|
|
{
|
|
case "$1" in
|
|
nfs)
|
|
echo 0 >"${PROCFS_PATH}/fs/nfsd/threads"
|
|
basic_stop "nfs" >/dev/null 2>&1 || true
|
|
pkill -9 nfsd
|
|
;;
|
|
nlockmgr)
|
|
basic_stop "nfslock" >/dev/null 2>&1 || true
|
|
;;
|
|
*)
|
|
usage
|
|
esac
|
|
}
|
|
|
|
service_start ()
|
|
{
|
|
case "$1" in
|
|
nfs)
|
|
basic_start "nfs"
|
|
;;
|
|
nlockmgr)
|
|
basic_start "nfslock"
|
|
;;
|
|
*)
|
|
usage
|
|
esac
|
|
}
|
|
|
|
##################################################
|
|
# 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"
|
|
if [ "$_f" ] ; then
|
|
echo 1 >"$_f"
|
|
fi
|
|
}
|
|
|
|
##################################################
|
|
# monitor-post support
|
|
|
|
nfs_check_thread_count ()
|
|
{
|
|
# Load NFS configuration to get desired number of threads.
|
|
if [ -r "$nfs_config" ] ; then
|
|
. "$nfs_config"
|
|
fi
|
|
|
|
# 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}}"
|
|
[ -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.
|
|
read _running_threads <"$_threads_file"
|
|
# Intentionally not arithmetic comparison - avoids extra errors
|
|
# when above fails...
|
|
if [ "$_running_threads" != "$_configured_threads" ] ; then
|
|
echo "Attempting to correct number of nfsd threads from ${_running_threads} to ${_configured_threads}"
|
|
echo "$_configured_threads" >"$_threads_file"
|
|
fi
|
|
}
|
|
|
|
##################################################
|
|
# list share directories
|
|
|
|
nfs_monitor_list_shares ()
|
|
{
|
|
_cache_file="${CTDB_NFS_CALLOUT_STATE_DIR}/list_shares_cache"
|
|
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"
|
|
}
|
|
|
|
##################################################
|
|
|
|
nfs_register ()
|
|
{
|
|
cat <<EOF
|
|
shutdown
|
|
startup
|
|
stop
|
|
start
|
|
monitor-list-shares
|
|
monitor-post
|
|
EOF
|
|
}
|
|
|
|
##################################################
|
|
|
|
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
|
|
;;
|
|
register)
|
|
nfs_register
|
|
;;
|
|
monitor-pre|releaseip|takeip)
|
|
# Not required/implemented
|
|
:
|
|
;;
|
|
*)
|
|
usage
|
|
esac
|