From 55d4b3438f2c44a12b4c513ef26e2d1c4fa9f5b4 Mon Sep 17 00:00:00 2001 From: Martin Schwenke Date: Fri, 12 Feb 2021 19:14:12 +1100 Subject: [PATCH] ctdb-scripts: Factor out function dump_stacks() Signed-off-by: Martin Schwenke Reviewed-by: Amitay Isaacs --- ctdb/config/debug_locks.sh | 64 +++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/ctdb/config/debug_locks.sh b/ctdb/config/debug_locks.sh index 1f89cb7353c..6f012bd3355 100755 --- a/ctdb/config/debug_locks.sh +++ b/ctdb/config/debug_locks.sh @@ -28,6 +28,44 @@ fi # Load/cache database options from configuration file ctdb_get_db_options +dump_stack () +{ + _pid="$1" + + echo "----- Stack trace for PID=${_pid} -----" + # x is intentionally ignored + # shellcheck disable=SC2034 + read x x state x <"/proc/${_pid}/stat" + if [ "$state" = "D" ] ; then + # Don't run gstack on a process in D state since + # gstack will hang until the process exits D state. + # Although it is possible for a process to transition + # to D state after this check, it is unlikely because + # if a process is stuck in D state then it is probably + # the reason why this script was called. Note that a + # kernel stack almost certainly won't help diagnose a + # deadlock... but it will probably give us someone to + # blame! + echo "----- Process in D state, printing kernel stack only" + cat "/proc/${_pid}/stack" + else + gstack "$_pid" + fi +} + +dump_stacks () +{ + _pids="$1" + + # Use word splitting to squash whitespace + # shellcheck disable=SC2086 + _pids=$(echo $_pids | tr ' ' '\n' | sort -u) + + for _pid in $_pids; do + dump_stack "$_pid" + done +} + ( flock -n 9 || exit 1 @@ -61,32 +99,8 @@ ctdb_get_db_options pids=$(echo "$out" | grep -v "W$" | grep "$db" | grep -v ctdbd | awk '{print $1}') all_pids="$all_pids $pids" done - # Use word splitting to squash whitespace - # shellcheck disable=SC2086 - pids=$(echo $all_pids | tr ' ' '\n' | sort -u) - # For each process waiting, log stack trace - for pid in $pids ; do - echo "----- Stack trace for PID=$pid -----" - # x is intentionally ignored - # shellcheck disable=SC2034 - read x x state x <"/proc/${pid}/stat" - if [ "$state" = "D" ] ; then - # Don't run gstack on a process in D state since - # gstack will hang until the process exits D state. - # Although it is possible for a process to transition - # to D state after this check, it is unlikely because - # if a process is stuck in D state then it is probably - # the reason why this script was called. Note that a - # kernel stack almost certainly won't help diagnose a - # deadlock... but it will probably give us someone to - # blame! - echo "----- Process in D state, printing kernel stack only" - cat "/proc/${pid}/stack" - else - gstack "$pid" - fi - done + dump_stacks "$all_pids" fi echo "===== End of debug locks PID=$$ ====="