summaryrefslogtreecommitdiffstats
path: root/ctdb/config/nfs-linux-kernel-callout
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-05 17:47:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-05 17:47:29 +0000
commit4f5791ebd03eaec1c7da0865a383175b05102712 (patch)
tree8ce7b00f7a76baa386372422adebbe64510812d4 /ctdb/config/nfs-linux-kernel-callout
parentInitial commit. (diff)
downloadsamba-upstream.tar.xz
samba-upstream.zip
Adding upstream version 2:4.17.12+dfsg.upstream/2%4.17.12+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ctdb/config/nfs-linux-kernel-callout')
-rwxr-xr-xctdb/config/nfs-linux-kernel-callout441
1 files changed, 441 insertions, 0 deletions
diff --git a/ctdb/config/nfs-linux-kernel-callout b/ctdb/config/nfs-linux-kernel-callout
new file mode 100755
index 0000000..f2f3e38
--- /dev/null
+++ b/ctdb/config/nfs-linux-kernel-callout
@@ -0,0 +1,441 @@
+#!/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}"
+
+# As above, edit the default value below. CTDB_NFS_DISTRO_STYLE is a
+# test variable only.
+nfs_distro_style="${CTDB_NFS_DISTRO_STYLE:-systemd-redhat}"
+
+# As above, edit the default value below. CTDB_SYS_ETCDIR is a
+# test variable only.
+etc_dir="${CTDB_SYS_ETCDIR:-/etc}"
+
+# A value of "AUTO" for any service means that service is usually
+# automatically started and stopped by one of the other services.
+# Such services will still be restarted by hand on failure, if
+# configured to do so. This allows services that should not be
+# running to be set to "".
+
+case "$nfs_distro_style" in
+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_dir}/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
+ ;;
+
+sysvinit-*)
+ # Defaults
+ nfs_service="nfs"
+ nfs_lock_service="AUTO"
+ nfs_mountd_service="AUTO"
+ nfs_status_service="AUTO"
+ nfs_rquotad_service="AUTO"
+ nfs_config="${etc_dir}/sysconfig/nfs"
+ nfs_rquotad_config="$nfs_config"
+
+ case "$nfs_distro_style" in
+ *-redhat)
+ nfs_lock_service="nfslock"
+ ;;
+ *-suse)
+ nfs_service="nfsserver"
+ ;;
+ *-debian)
+ nfs_service="nfs-kernel-server"
+ nfs_config="${etc_dir}/default/nfs-kernel-server"
+ nfs_rquotad_config="${etc_dir}/default/quota"
+ ;;
+ *)
+ echo "Internal error"
+ exit 1
+ ;;
+ esac
+ ;;
+
+*)
+ echo "Internal error"
+ exit 1
+ ;;
+esac
+
+# 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
+}
+
+##################################################
+
+nfs_load_config()
+{
+ _config="${1:-${nfs_config}}"
+
+ if [ -r "$_config" ]; then
+ . "$_config"
+ fi
+}
+
+##################################################
+
+service_is_auto_started()
+{
+ [ "$1" = "AUTO" ]
+}
+
+service_is_defined()
+{
+ _service="$1"
+
+ [ -n "$_service" ] && ! service_is_auto_started "$_service"
+}
+
+service_if_defined()
+{
+ _service="$1"
+ _action="$2"
+
+ if service_is_defined "$_service"; then
+ service "$_service" "$_action"
+ fi
+}
+
+##################################################
+# Overall NFS service stop and start
+
+nfs_service_stop()
+{
+ service_if_defined "$nfs_rquotad_service" stop
+
+ service "$nfs_service" stop
+
+ service_if_defined "$nfs_lock_service" stop
+}
+
+nfs_service_start()
+{
+ service_if_defined "$nfs_lock_service" start
+
+ service "$nfs_service" start
+
+ service_if_defined "$nfs_rquotad_service" start
+}
+
+##################################################
+# service "stop" and "start" options for restarting
+
+manual_stop()
+{
+ case "$1" in
+ mountd)
+ killall -q -9 rpc.mountd
+ ;;
+ rquotad)
+ killall -q -9 rpc.rquotad
+ ;;
+ status)
+ killall -q -9 rpc.statd
+ ;;
+ *)
+ echo "$0: Internal error - invalid call to manual_stop()"
+ exit 1
+ ;;
+ esac
+}
+
+service_or_manual_stop()
+{
+ _rpc_service="$1"
+ _system_service="$2"
+
+ if service_is_defined "$_system_service"; then
+ service "$_system_service" stop
+ elif service_is_auto_started "$_system_service"; then
+ manual_stop "$_rpc_service"
+ fi
+}
+
+service_stop()
+{
+ _rpc_service="$1"
+
+ case "$_rpc_service" in
+ nfs)
+ echo 0 >"${PROCFS_PATH}/fs/nfsd/threads"
+ nfs_service_stop >/dev/null 2>&1 || true
+ pkill -9 nfsd
+ ;;
+ nlockmgr)
+ if service_is_defined "$nfs_lock_service" ; then
+ service "$nfs_lock_service" stop >/dev/null 2>&1 || true
+ else
+ service "$nfs_service" stop >/dev/null 2>&1 || true
+ fi
+ ;;
+ mountd)
+ service_or_manual_stop "$_rpc_service" "$nfs_mountd_service"
+ ;;
+ rquotad)
+ service_or_manual_stop "$_rpc_service" "$nfs_rquotad_service"
+ ;;
+ status)
+ service_or_manual_stop "$_rpc_service" "$nfs_status_service"
+ ;;
+ *)
+ usage
+ ;;
+ esac
+}
+
+manual_start()
+{
+ case "$1" in
+ mountd)
+ nfs_load_config
+ if [ -z "$RPCMOUNTDOPTS" ]; then
+ RPCMOUNTDOPTS="${MOUNTD_PORT:+-p }$MOUNTD_PORT"
+ fi
+ # shellcheck disable=SC2086
+ rpc.mountd $RPCMOUNTDOPTS
+ ;;
+ rquotad)
+ nfs_load_config "$nfs_rquotad_config"
+ if [ -z "$RPCRQUOTADOPTS" ]; then
+ RPCRQUOTADOPTS="${RQUOTAD_PORT:+-p }$RQUOTAD_PORT"
+ fi
+ # shellcheck disable=SC2086
+ rpc.rquotad $RPCRQUOTADOPTS
+ ;;
+ status)
+ 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
+ ;;
+ *)
+ echo "$0: Internal error - invalid call to manual_start()"
+ exit 1
+ ;;
+ esac
+}
+
+service_or_manual_start()
+{
+ _rpc_service="$1"
+ _system_service="$2"
+
+ if service_is_defined "$_system_service"; then
+ service "$_system_service" start
+ elif service_is_auto_started "$_system_service"; then
+ manual_start "$_rpc_service"
+ fi
+}
+
+service_start()
+{
+ _rpc_service="$1"
+
+ case "$_rpc_service" in
+ nfs)
+ nfs_service_start
+ ;;
+ nlockmgr)
+ if service_is_defined "$nfs_lock_service" ; then
+ service "$nfs_lock_service" start
+ else
+ service "$nfs_service" start
+ fi
+ ;;
+ mountd)
+ service_or_manual_start "$_rpc_service" "$nfs_mountd_service"
+ ;;
+ rquotad)
+ service_or_manual_start "$_rpc_service" "$nfs_rquotad_service"
+ ;;
+ status)
+ service_or_manual_start "$_rpc_service" "$nfs_status_service"
+ ;;
+ *)
+ usage
+ ;;
+ esac
+}
+
+##################################################
+# service init startup and final shutdown
+
+nfs_shutdown()
+{
+ nfs_service_stop
+}
+
+nfs_startup()
+{
+ nfs_service_stop || true
+ nfs_service_start
+ _f="${PROCFS_PATH}/sys/net/ipv4/tcp_tw_recycle"
+ if [ -f "$_f" ]; then
+ echo 1 >"$_f"
+ fi
+}
+
+##################################################
+# monitor-post support
+
+nfs_check_thread_count()
+{
+ # Load NFS configuration to get desired number of threads.
+ nfs_load_config
+
+ # 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}}"
+ if [ -z "$_configured_threads" ] && type nfsconf >/dev/null 2>&1; then
+ _configured_threads=$(nfsconf --get nfsd threads) || true
+ fi
+ [ -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 -r _running_threads <"$_threads_file" || {
+ echo "WARNING: Reading \"${_threads_file}\" unexpectedly failed"
+ exit 0
+ }
+
+ # Intentionally not arithmetic comparison - avoids extra errors
+ # when above read fails in an unexpected way...
+ 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"
+ # -nt operator is well supported in Linux: dash, bash, ksh, ...
+ # shellcheck disable=SC2039,SC3013
+ 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 | releaseip-pre | takeip-pre)
+ # Not required/implemented
+ :
+ ;;
+*)
+ usage
+ ;;
+esac