ctdb-scripts: Dump stack traces of smbd processes after shutdown
[samba.git] / ctdb / config / events.d / 50.samba
index 4b53cba01be6f9736a25a2509df692755fc7b73a..4ed892cdc5905e3efaa45e9441109a59e781c2f7 100755 (executable)
@@ -2,9 +2,9 @@
 # ctdb event script for Samba
 
 [ -n "$CTDB_BASE" ] || \
-    export CTDB_BASE=$(cd -P $(dirname "$0") ; dirname "$PWD")
+    CTDB_BASE=$(d=$(dirname "$0") ; cd -P "$d" ; dirname "$PWD")
 
-. $CTDB_BASE/functions
+. "${CTDB_BASE}/functions"
 
 detect_init_style
 
@@ -24,11 +24,13 @@ case $CTDB_INIT_STYLE in
                ;;
 esac
 
+# service_name is used by various functions
+# shellcheck disable=SC2034
 service_name="samba"
 
 loadconfig
 
-ctdb_setup_service_state_dir
+service_state_dir=$(ctdb_setup_service_state_dir) || exit $?
 
 service_start ()
 {
@@ -63,6 +65,7 @@ service_start ()
 service_stop ()
 {
     service "$CTDB_SERVICE_SMB" stop
+    program_stack_traces "smbd" 5
     if [ -n "$CTDB_SERVICE_NMB" ] ; then
        service "$CTDB_SERVICE_NMB" stop
     fi
@@ -78,19 +81,42 @@ testparm_foreground_update ()
 {
     _timeout="$1"
 
-    if ! _out=$(timeout $_timeout testparm -v -s 2>/dev/null) ; then
-       if [ -f "$smbconf_cache" ] ; then
-           echo "WARNING: smb.conf cache update failed - using old cache file"
-           return 1
-       else
-           die "ERROR: smb.conf cache create failed"
-       fi
-    fi
-
+    # No need to remove these temporary files, since there are only 2
+    # of them.
+    _out="${smbconf_cache}.out"
+    _err="${smbconf_cache}.err"
+
+    timeout "$_timeout" testparm -v -s >"$_out" 2>"$_err"
+    case $? in
+       0) : ;;
+       124)
+           if [ -f "$smbconf_cache" ] ; then
+               echo "WARNING: smb.conf cache update timed out - using old cache file"
+               return 1
+           else
+               echo "ERROR: smb.conf cache create failed - testparm command timed out"
+               exit 1
+           fi
+           ;;
+       *)
+           if [ -f "$smbconf_cache" ] ; then
+               echo "WARNING: smb.conf cache update failed - using old cache file"
+               cat "$_err"
+               return 1
+           else
+               echo "ERROR: smb.conf cache create failed - testparm failed with:"
+               cat "$_err"
+               exit 1
+           fi
+    esac
+
+    # Only using $$ here to avoid a collision.  This is written into
+    # CTDB's own state directory so there is no real need for a secure
+    # temporary file.
     _tmpfile="${smbconf_cache}.$$"
     # Patterns to exclude...
-    pat='^[[:space:]]+(registry[[:space:]]+shares|include|copy|winbind[[:space:]]+separator)[[:space:]]+='    
-    echo "$_out" | grep -Ev "$pat" >"$_tmpfile"
+    _pat='^[[:space:]]+(registry[[:space:]]+shares|include|copy|winbind[[:space:]]+separator)[[:space:]]+='
+    grep -Ev "$_pat" <"$_out" >"$_tmpfile"
     mv "$_tmpfile" "$smbconf_cache" # atomic
 
     return 0
@@ -100,7 +126,7 @@ testparm_background_update ()
 {
     _timeout="$1"
 
-    testparm_foreground_update $_timeout >/dev/null 2>&1 </dev/null &
+    testparm_foreground_update "$_timeout" >/dev/null 2>&1 </dev/null &
 }
 
 testparm_cat ()
@@ -130,15 +156,15 @@ is_ctdb_managed_service || exit 0
 ###########################
 
 case "$1" in
-     startup)
+startup)
        ctdb_service_start
        ;;
 
-     shutdown)
+shutdown)
        ctdb_service_stop
        ;;
 
-     monitor)
+monitor)
        testparm_foreground_update 10
        ret=$?
 
@@ -147,6 +173,8 @@ case "$1" in
            smb_ports=$(list_samba_ports)
            [ -n "$smb_ports" ] || die "Failed to set smb ports"
        fi
+       # Intentionally unquoted multi-word value here
+       # shellcheck disable=SC2086
        ctdb_check_tcp_ports $smb_ports || exit $?
 
        if [ "$CTDB_SAMBA_SKIP_SHARE_CHECK" != "yes" ] ; then
@@ -157,10 +185,6 @@ case "$1" in
            testparm_background_update 10
        fi
        ;;
-
-    *)
-       ctdb_standard_event_handler "$@"
-       ;;
 esac
 
 exit 0