ctdb-scripts: Parameterise 60.nfs with $CTDB_NFS_CALLOUT
authorMartin Schwenke <martin@meltin.net>
Wed, 24 Jun 2015 11:36:14 +0000 (21:36 +1000)
committerAmitay Isaacs <amitay@samba.org>
Tue, 14 Jul 2015 07:57:18 +0000 (09:57 +0200)
The goal is to have a single NFS eventscript.

Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
16 files changed:
ctdb/config/events.d/60.nfs
ctdb/config/nfs-checks.d/20.nfs.check
ctdb/config/nfs-checks.d/30.nlockmgr.check
ctdb/config/nfs-linux-kernel-callout [new file with mode: 0755]
ctdb/config/statd-callout
ctdb/doc/ctdbd.conf.5.xml
ctdb/packaging/RPM/ctdb.spec.in
ctdb/tests/eventscripts/60.nfs.monitor.102.sh
ctdb/tests/eventscripts/60.nfs.monitor.103.sh
ctdb/tests/eventscripts/60.nfs.monitor.104.sh
ctdb/tests/eventscripts/60.nfs.monitor.113.sh
ctdb/tests/eventscripts/60.nfs.monitor.114.sh
ctdb/tests/eventscripts/60.nfs.monitor.143.sh
ctdb/tests/eventscripts/etc-ctdb/nfs-linux-kernel-callout [new symlink]
ctdb/tests/eventscripts/scripts/local.sh
ctdb/wscript

index 997d676091bfd7333b002f4687a875ab01e9e470..191af667a7f8a117ad76f93ab58f7251a1e2c0d7 100755 (executable)
@@ -7,16 +7,18 @@
 . $CTDB_BASE/functions
 
 service_name="nfs"
-service_start ()
-{
-    startstop_nfs stop
-    startstop_nfs start
-    set_proc "sys/net/ipv4/tcp_tw_recycle" 1
-}
-service_stop ()
+
+if [ -z "$CTDB_NFS_CALLOUT" ] ; then
+    CTDB_NFS_CALLOUT="${CTDB_BASE}/nfs-linux-kernel-callout"
+fi
+# Always export, for statd callout
+export CTDB_NFS_CALLOUT
+
+nfs_callout ()
 {
-    startstop_nfs stop
+    eval "$CTDB_NFS_CALLOUT" "$@"
 }
+
 service_reconfigure ()
 {
     # Restart lock manager, notify clients
@@ -25,29 +27,6 @@ service_reconfigure ()
     fi >/dev/null 2>&1
 }
 
-nfs_check_thread_count ()
-{
-    [ "$CTDB_MONITOR_NFS_THREAD_COUNT" = "yes" ] || return 0
-
-    # 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
-
-    # nfsd should be running the configured number of threads.  If
-    # there are a different number of threads then tell nfsd the
-    # correct number.  
-    _running_threads=$(get_proc "fs/nfsd/threads")
-    # Intentionally not arithmetic comparison - avoids extra errors
-    # when get_proc() fails...
-    if [ "$_running_threads" != "$_configured_threads" ] ; then
-       echo "Attempting to correct number of nfsd threads from ${_running_threads} to ${_configured_threads}"
-       set_proc "fs/nfsd/threads" "$_configured_threads"
-    fi
-}
-
 loadconfig
 
 [ "${CTDB_NFS_SERVER_MODE:-${NFS_SERVER_MODE}}" != "ganesha" ] || exit 0
@@ -60,41 +39,40 @@ is_ctdb_managed_service || exit 0
 
 ctdb_service_check_reconfigure
 
-case "$1" in 
-     init)
-       # read statd from persistent database
-       ;;
-     startup)
-       ctdb_service_start
+case "$1" in
+    startup)
+       nfs_callout "$@"
        ;;
 
-     shutdown)
-       ctdb_service_stop
+    shutdown)
+        nfs_callout "$@"
        ;;
 
-     takeip)
+    takeip)
+       nfs_callout "$@"
        ctdb_service_set_reconfigure
        ;;
 
-     releaseip)
+    releaseip)
+       nfs_callout "$@"
        ctdb_service_set_reconfigure
        ;;
 
-      monitor)
-       # Check that directories for shares actually exist.
-       [ "$CTDB_NFS_SKIP_SHARE_CHECK" = "yes" ] || {
-           exportfs -v | grep '^/' | 
-           sed -r -e 's@[[:space:]]+[^[:space:]()]+\([^[:space:]()]+\)$@@' | 
-           sort -u | 
-           ctdb_check_directories 
-       } || exit $?
+    monitor)
+       nfs_callout "monitor-pre" || exit $?
+
+       # Check that directories for shares actually exist
+       if [ "$CTDB_NFS_SKIP_SHARE_CHECK" != "yes" ] ; then
+           nfs_callout "monitor-list-shares" | ctdb_check_directories || \
+               exit $?
+       fi
 
        update_tickles 2049
        nfs_update_lock_info
 
        nfs_check_services
 
-       nfs_check_thread_count
+       nfs_callout "monitor-post" || exit $?
                ;;
 
     *)
index 7229f7d9fe0892edd58a44db84b7c12f1187b96f..dad1cdc11363b67cfaaaa810bede69f414737b66 100644 (file)
@@ -2,6 +2,6 @@
 version="3"
 restart_every=10
 unhealthy_after=2
-service_stop_cmd="startstop_nfs restart-stop"
-service_start_cmd="startstop_nfs start"
+service_stop_cmd="$CTDB_NFS_CALLOUT stop nfs"
+service_start_cmd="$CTDB_NFS_CALLOUT start nfs"
 service_debug_cmd="program_stack_traces nfsd 5"
index c2e723e10519e8464b61b69c8d1dc192a4c8f048..6660ca0d91c43da0c41c84b518046aa08e982f6d 100644 (file)
@@ -2,5 +2,5 @@
 version="4"
 restart_every=2
 unhealthy_after=6
-service_stop_cmd="startstop_nfslock stop"
-service_start_cmd="startstop_nfslock start"
+service_stop_cmd="$CTDB_NFS_CALLOUT stop nlockmgr"
+service_start_cmd="$CTDB_NFS_CALLOUT start nlockmgr"
diff --git a/ctdb/config/nfs-linux-kernel-callout b/ctdb/config/nfs-linux-kernel-callout
new file mode 100755 (executable)
index 0000000..59618d7
--- /dev/null
@@ -0,0 +1,205 @@
+#!/bin/sh
+
+# Exit on 1st error
+set -e
+
+# 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 }
+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 ()
+{
+    exportfs -v |
+       grep '^/' |
+       sed -e 's@[[:space:]][[:space:]]*[^[:space:]()][^[:space:]()]*([^[:space:]()][^[:space:]()]*)$@@' |
+       sort -u
+}
+
+##################################################
+
+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
+       ;;
+    monitor-pre|releaseip|takeip)
+       # Not required/implemented
+       :
+       ;;
+    *)
+       usage
+esac
index 347af41a7cd5fdc9a84c3d9f95f1abca068ed07f..53a2e4b7911511a2920b45288ef4e1b6b6aaa674 100755 (executable)
@@ -116,15 +116,15 @@ case "$1" in
        # service is started.
        state_even=$(( $(date '+%s') / 2 * 2))
 
-       # we must also let some time pass between stopping and restarting the
-       # lockmanager since othervise there is a window where the lockmanager
-       # will respond "strangely" immediately after restarting it, which
-       # causes clients to fail to reclaim the locks.
-       # 
+       # We must also let some time pass between stopping and
+       # restarting the lock manager.  Otherwise there is a window
+       # where the lock manager will respond "strangely" immediately
+       # after restarting it, which causes clients to fail to reclaim
+       # their locks.
        if [ "${CTDB_NFS_SERVER_MODE:-${NFS_SERVER_MODE}}" != "ganesha" ] ; then
-            startstop_nfslock stop >/dev/null 2>&1
+           "$CTDB_NFS_CALLOUT" "stop" "nlockmgr" >/dev/null 2>&1
             sleep 2
-            startstop_nfslock start >/dev/null 2>&1
+           "$CTDB_NFS_CALLOUT" "start" "nlockmgr" >/dev/null 2>&1
        fi
 
        # we now need to send out additional statd notifications to ensure
index bb44317a42bb510954fd7de8a4d703a43572abf2..a0335832306c6ba8607eacdcecd0e33a2048fb99 100644 (file)
@@ -1055,6 +1055,21 @@ CTDB_PER_IP_ROUTING_TABLE_ID_HIGH=9000
          </listitem>
        </varlistentry>
 
+       <varlistentry>
+         <term>CTDB_NFS_CALLOUT=<parameter>COMMAND</parameter></term>
+         <listitem>
+           <para>
+             COMMAND specifies the path to a callout to handle
+             interactions with the configured NFS system, including
+             startup, shutdown, monitoring.
+           </para>
+           <para>
+             Default is the included
+             <command>nfs-linux-kernel-callout</command>.
+           </para>
+         </listitem>
+       </varlistentry>
+
        <varlistentry>
          <term>CTDB_NFS_DUMP_STUCK_THREADS=<parameter>NUM</parameter></term>
          <listitem>
index 503670023b8cc16884dbb4ad046339e375e3ba57..25d2be7e2b5f42dbcf36c90763754682198c3b74 100644 (file)
@@ -191,6 +191,7 @@ rm -rf $RPM_BUILD_ROOT
 %config(noreplace) %{_sysconfdir}/ctdb/nfs-checks.d/40.mountd.check
 %config(noreplace) %{_sysconfdir}/ctdb/nfs-checks.d/50.rquotad.check
 %{_sysconfdir}/ctdb/statd-callout
+%{_sysconfdir}/ctdb/nfs-linux-kernel-callout
 %{_sbindir}/ctdbd
 %{_sbindir}/ctdbd_wrapper
 %{_bindir}/ctdb
index bb988aa9a2d11689f17ee1629cfa0cd2007130c4..509dc2a705e25013f4247ac33e5fb4389ac0e541 100755 (executable)
@@ -8,7 +8,7 @@ setup_nfs
 
 CTDB_MONITOR_NFS_THREAD_COUNT="yes"
 RPCNFSDCOUNT=8
-FAKE_NFSD_THREAD_PIDS="1 2 3 4 5 6 7 8"
+nfs_setup_fake_threads "nfsd" 1 2 3 4 5 6 7 8
 
 ok_null
 
index 75d7291fb8587f529abf1d3da84b262c3e345b7e..2bf44f0efa988424d5620224a6652d7adeea9753 100755 (executable)
@@ -8,7 +8,7 @@ setup_nfs
 
 CTDB_MONITOR_NFS_THREAD_COUNT="yes"
 RPCNFSDCOUNT=8
-FAKE_NFSD_THREAD_PIDS="1 2 3 4 5"
+nfs_setup_fake_threads "nfsd" 1 2 3 4 5
 
 ok "Attempting to correct number of nfsd threads from 5 to 8"
 
index a052be813194d09f83f655a5f09e95bda9ea442a..64831ee343417fecff1a4ecfd2266d10ab597d72 100755 (executable)
@@ -11,7 +11,7 @@ setup_nfs
 
 CTDB_MONITOR_NFS_THREAD_COUNT="yes"
 RPCNFSDCOUNT=4
-FAKE_NFSD_THREAD_PIDS="1 2 3 4 5 6"
+nfs_setup_fake_threads "nfsd" 1 2 3 4 5 6
 
 ok "Attempting to correct number of nfsd threads from 6 to 4"
 
index 711d5a9a1f87ec36329ed0bc5edbb9296d598d48..dae9db3f8ed8c860912990d497a688e2d1f913c2 100755 (executable)
@@ -10,6 +10,6 @@ rpc_services_down "nfs"
 
 # Additionally, any hung threads should have stack traces dumped.
 CTDB_NFS_DUMP_STUCK_THREADS=5
-FAKE_NFSD_THREAD_PIDS=""
+nfs_setup_fake_threads "nfsd"
 
 nfs_iterate_test 10 "nfs"
index 55fe66d041bb38bdc2ccb441feb0c61983847275..00f30c5d7403c133e746e47fd9b6c31a284ebc0e 100755 (executable)
@@ -10,6 +10,6 @@ rpc_services_down "nfs"
 
 # Additionally, any hung threads should have stack traces dumped.
 CTDB_NFS_DUMP_STUCK_THREADS=5
-FAKE_NFSD_THREAD_PIDS="1001 1002 1003"
+nfs_setup_fake_threads "nfsd" 1001 1002 1003
 
 nfs_iterate_test 10 "nfs"
index 4ed0dcf474ac3de0e75d153d0d2c8cdb189ae37e..34a4c80e49cc3bdef44c5f8640b814f43cae1616 100755 (executable)
@@ -9,6 +9,6 @@ define_test "statd down, 2 iterations, stuck process"
 setup_nfs
 rpc_services_down "status"
 CTDB_NFS_DUMP_STUCK_THREADS=2
-FAKE_RPC_THREAD_PIDS="1001"
+nfs_setup_fake_threads "rpc.status" 1001
 
 nfs_iterate_test 2 "status"
diff --git a/ctdb/tests/eventscripts/etc-ctdb/nfs-linux-kernel-callout b/ctdb/tests/eventscripts/etc-ctdb/nfs-linux-kernel-callout
new file mode 120000 (symlink)
index 0000000..29858c2
--- /dev/null
@@ -0,0 +1 @@
+../../../config/nfs-linux-kernel-callout
\ No newline at end of file
index b13399e97c3e3e55febfde127f5356662cabd205..a1ba67d9981b8b9aef9b2fc14ded865bc41c1932 100644 (file)
@@ -789,8 +789,8 @@ setup_nfs ()
 
     export CTDB_NFS_SKIP_SHARE_CHECK="no"
 
-    export CTDB_MONITOR_NFS_THREAD_COUNT RPCNFSDCOUNT FAKE_NFSD_THREAD_PIDS
-    export CTDB_NFS_DUMP_STUCK_THREADS FAKE_RPC_THREAD_PIDS
+    export CTDB_MONITOR_NFS_THREAD_COUNT RPCNFSDCOUNT
+    export CTDB_NFS_DUMP_STUCK_THREADS
 
     # Reset the failcounts for nfs services.
     eventscript_call eval rm -f '$ctdb_fail_dir/nfs_*'
@@ -805,6 +805,9 @@ setup_nfs ()
        export CTDB_MANAGED_SERVICES="foo nfs bar"
 
        rpc_services_up "nfs" "mountd" "rquotad" "nlockmgr" "status"
+
+       nfs_setup_fake_threads "nfsd"
+       nfs_setup_fake_threads "rpc.foobar"  # Just set the variable to empty
     else
        debug "Setting up NFS environment: all RPC services down, NFS not managed by CTDB"
 
@@ -876,6 +879,24 @@ nfs_load_config ()
     done
 }
 
+nfs_setup_fake_threads ()
+{
+    _prog="$1" ; shift
+
+    case "$_prog" in
+       nfsd)
+           export PROCFS_PATH=$(mktemp -d --tmpdir="$EVENTSCRIPTS_TESTS_VAR_DIR")
+           _threads="${PROCFS_PATH}/fs/nfsd/threads"
+           mkdir -p $(dirname "$_threads")
+           echo $# >"$_threads"
+           export FAKE_NFSD_THREAD_PIDS="$*"
+           ;;
+       *)
+           export FAKE_RPC_THREAD_PIDS="$*"
+           ;;
+    esac
+}
+
 program_stack_traces ()
 {
     _prog="$1"
@@ -896,10 +917,10 @@ EOF
 guess_output ()
 {
     case "$1" in
-       startstop_nfslock\ start)
+       $CTDB_NFS_CALLOUT\ start\ nlockmgr)
            echo "&Starting nfslock: OK"
            ;;
-       startstop_nfs\ start)
+       $CTDB_NFS_CALLOUT\ start\ nfs)
            cat <<EOF
 &Starting nfslock: OK
 &Starting nfs: OK
index 7b3304b10a8e7c599796d3f03fca0a2368d94cfa..06f86a31916f16a7729c2cf3115d02f1262dd87f 100755 (executable)
@@ -486,6 +486,7 @@ def build(bld):
         'debug-hung-script.sh',
         'debug_locks.sh',
         'gcore_trace.sh',
+        'nfs-linux-kernel-callout',
         'notify.sh',
         'statd-callout'
     ]
@@ -628,6 +629,7 @@ def build(bld):
         'events.d',
         'functions',
         'nfs-checks.d',
+        'nfs-linux-kernel-callout',
         'statd-callout'
     ]