3 # This script parses /proc/locks and finds the processes that are holding
4 # locks on CTDB databases. For all those processes the script dumps a
7 # This script can be used only if Samba is configured to use fcntl locks
8 # rather than mutex locks.
10 [ -n "$CTDB_BASE" ] || \
11 CTDB_BASE
=$
(d
=$
(dirname "$0") ; cd -P "$d" ; echo "$PWD")
13 .
"${CTDB_BASE}/functions"
15 # Default fallback location for database directories.
16 # These can be overwritten from CTDB configuration
17 CTDB_DBDIR
="${CTDB_VARDIR}"
18 CTDB_DBDIR_PERSISTENT
="${CTDB_VARDIR}/persistent"
25 echo "===== Start of debug locks PID=$$ ====="
27 # Create sed expression to convert inodes to names.
28 # Filenames don't contain dashes and we want basenames
29 # shellcheck disable=SC2035
30 sed_cmd
=$
(cd "$CTDB_DBDIR" &&
31 stat
-c "s#[0-9a-f]*:[0-9a-f]*:%i #%n #" *.tdb.
* 2>/dev
/null
;
32 cd "$CTDB_DBDIR_PERSISTENT" &&
33 stat
-c "s#[0-9a-f]*:[0-9a-f]*:%i #%n #" *.tdb.
* 2>/dev
/null
)
35 # Parse /proc/locks and extract following information
36 # pid process_name tdb_name offsets [W]
37 out
=$
( grep -F "POSIX ADVISORY WRITE" /proc
/locks |
38 awk '{ if($2 == "->") { print $6, $7, $8, $9, "W" } else { print $5, $6, $7, $8 } }' |
39 while read pid rest
; do
40 pname
=$
(readlink
"/proc/${pid}/exe")
41 echo "$pid $pname $rest"
42 done |
sed -e "$sed_cmd" |
grep "\.tdb" )
44 if [ -n "$out" ]; then
45 # Log information about locks
48 # Find processes that are waiting for locks
49 dbs
=$
(echo "$out" |
grep "W$" |
awk '{print $3}')
52 pids
=$
(echo "$out" |
grep -v "W$" |
grep "$db" |
grep -v ctdbd |
awk '{print $1}')
53 all_pids
="$all_pids $pids"
55 # Use word splitting to squash whitespace
56 # shellcheck disable=SC2086
57 pids
=$
(echo $all_pids |
tr " " "\n" |
sort -u)
59 # For each process waiting, log stack trace
61 echo "----- Stack trace for PID=$pid -----"
62 # x is intentionally ignored
63 # shellcheck disable=SC2034
64 read x x state x
<"/proc/${pid}/stat"
65 if [ "$state" = "D" ] ; then
66 # Don't run gstack on a process in D state since
67 # gstack will hang until the process exits D state.
68 # Although it is possible for a process to transition
69 # to D state after this check, it is unlikely because
70 # if a process is stuck in D state then it is probably
71 # the reason why this script was called. Note that a
72 # kernel stack almost certainly won't help diagnose a
73 # deadlock... but it will probably give us someone to
75 echo "----- Process in D state, printing kernel stack only"
76 cat "/proc/${pid}/stack"
79 # gcore -o /var/log/core-deadlock-ctdb $pid
84 echo "===== End of debug locks PID=$$ ====="
85 )9>"${CTDB_SCRIPT_VARDIR}/debug_locks.lock" | script_log
"ctdbd-lock"