--- /dev/null
+#!/bin/sh
+
+. "${TEST_SCRIPTS_DIR}/unit.sh"
+
+define_test "knfsd down, 6 iterations, dump 5 threads, none hung"
+
+# knfsd fails and attempts to restart it fail.
+setup_nfs
+rpc_services_down "nfs"
+
+# Additionally, any hung threads should have stack traces dumped.
+CTDB_NFS_DUMP_STUCK_THREADS=5
+FAKE_NFSD_THREAD_PIDS=""
+
+iterate_test 6 'ok_null' \
+ 2 'rpc_set_service_failure_response "nfsd"' \
+ 4 'rpc_set_service_failure_response "nfsd"' \
+ 6 'rpc_set_service_failure_response "nfsd"'
--- /dev/null
+#!/bin/sh
+
+. "${TEST_SCRIPTS_DIR}/unit.sh"
+
+define_test "knfsd down, 6 iterations, dump 5 threads, 3 hung"
+
+# knfsd fails and attempts to restart it fail.
+setup_nfs
+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"
+
+iterate_test 6 'ok_null' \
+ 2 'rpc_set_service_failure_response "nfsd"' \
+ 4 'rpc_set_service_failure_response "nfsd"' \
+ 6 'rpc_set_service_failure_response "nfsd"'
fs/nfsd/threads)
echo "$FAKE_NFSD_THREAD_PIDS" | wc -w
;;
+ */stack)
+ echo "[<ffffffff87654321>] fake_stack_trace_for_pid_${1}+0x0/0xff"
+ ;;
*)
echo "get_proc: \"$1\" not implemented"
exit 1
export CTDB_NFS_SKIP_SHARE_CHECK="no"
export CTDB_MONITOR_NFS_THREAD_COUNT RPCNFSDCOUNT FAKE_NFSD_THREAD_PIDS
+ export CTDB_NFS_DUMP_STUCK_THREADS
# Reset the failcounts for nfs services.
eventscript_call eval rm -f '$ctdb_fail_dir/nfs_*'
case "${_progname}${_action#restart}" in
nfsd)
_t="\
-Trying to restart NFS service
+Trying to restart NFS service"
+
+ if [ -n "$CTDB_NFS_DUMP_STUCK_THREADS" ] ; then
+ for _pid in $FAKE_NFSD_THREAD_PIDS ; do
+ _t="\
+$_t
+Stack trace for stuck nfsd thread [${_pid}]:
+[<ffffffff87654321>] fake_stack_trace_for_pid_${_pid}/stack+0x0/0xff"
+ done
+ fi
+
+ _t="\
+${_t}
Starting nfslock: OK
Starting nfs: OK"
;;
--- /dev/null
+#!/bin/sh
+
+case "$1" in
+ nfsd)
+ echo "$FAKE_NFSD_THREAD_PIDS"
+ ;;
+ *)
+ echo "pidof: \"$1\" not implemented"
+ exit 1
+esac