initscript: Use a PID file to implement the "status" option
authorMartin Schwenke <martin@meltin.net>
Mon, 15 Apr 2013 05:18:12 +0000 (15:18 +1000)
committerAmitay Isaacs <amitay@gmail.com>
Fri, 19 Apr 2013 06:50:39 +0000 (16:50 +1000)
Using "ctdb ping" and "ctdb status" is fraught with danger.  These
commands can timeout when ctdbd is running, leading callers to believe
that ctdbd is not running.  Timeouts could be increased but we would
still have to handle potential timeouts.

Everything else in the world implements the "status" option by
checking if the relevant process is running.  This change makes CTDB
do the same thing and uses standard distro functions.

This change is backward compatible in sense that a missing
/var/run/ctdb/ directory means that we don't do a PID file check but
just depend on the distro's checking method.  Therefore, if CTDB was
started with an older version of this script then "service ctdb
status" will still work.

This script does not support changing the value of CTDB_VALGRIND
between calls.  If you start with CTDB_VALGRIND=yes then you need to
check status with the same setting.  CTDB_VALGRIND is a debug
variable, so this is acceptable.

This also adds sourcing of /lib/lsb/init-functions to make the Debian
function status_of_proc() available.

Signed-off-by: Martin Schwenke <martin@meltin.net>
Pair-programmed-with: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Michael Adam <obnox@samba.org>
(cherry picked from commit 687e2eace4f48400cf5029914f62b6ddabb85378)

Conflicts:
config/ctdb.init

config/ctdb.init

index 3c2412d5e4a4a1c46a8a2cd77703c790d81f5303..71629e684624252a8710b835fd62dfeb4dd2297d 100755 (executable)
@@ -6,7 +6,7 @@
 # chkconfig:           - 90 01
 #
 # description:                 Starts and stops the clustered tdb daemon
-# pidfile:             /var/run/ctdbd/ctdbd.pid
+# pidfile:             /var/run/ctdb/ctdbd.pid
 #
 
 ### BEGIN INIT INFO
@@ -32,6 +32,10 @@ fi
     LC_ALL=en_US.UTF-8
 }
 
+if [ -f /lib/lsb/init-functions ] ; then
+    . /lib/lsb/init-functions
+fi
+
 # Avoid using root's TMPDIR
 unset TMPDIR
 
@@ -54,6 +58,7 @@ detect_init_style
 export CTDB_INIT_STYLE
 
 ctdbd=${CTDBD:-/usr/sbin/ctdbd}
+pidfile="/var/run/ctdb/ctdbd.pid"
 
 if [ "$CTDB_VALGRIND" = "yes" ]; then
     init_style="valgrind"
@@ -88,6 +93,9 @@ build_ctdb_options () {
     }
     maybe_set "--reclock"                "$CTDB_RECOVERY_LOCK"
 
+    mkdir -p $(dirname "$pidfile")
+    maybe_set "--pidfile"                "$pidfile"
+
     # build up CTDB_OPTIONS variable from optional parameters
     maybe_set "--logfile"                "$CTDB_LOGFILE"
     maybe_set "--nlist"                  "$CTDB_NODES"
@@ -357,6 +365,8 @@ stop() {
     # make sure all ips are dropped, pfkill -9 might leave them hanging around
     drop_all_public_ips
 
+    rm -f "$pidfile"
+
     case $init_style in
        suse)
            # re-set the return code to the recorded RETVAL in order
@@ -379,30 +389,47 @@ restart() {
     start
 }
 
-status() {
-    echo -n $"Checking for ctdbd service: "
-    ctdb ping >/dev/null 2>&1 || {
-       RETVAL=$?
-       echo -n "  ctdbd not running. "
-       case $init_style in
-           suse)
-               set_retval $RETVAL
-               rc_status -v
-               ;;
-           redhat)
-               if [ -f /var/lock/subsys/ctdb ]; then
-                       echo $"ctdb dead but subsys locked"
-                       RETVAL=2
-               else
-                       echo $"ctdb is stopped"
-                       RETVAL=3
-               fi
-               ;;
-       esac
-       return $RETVAL
-    }
-    echo ""
-    ctdb status
+# Given that CTDB_VALGRIND is a debug option we don't support the pid
+# file.  We just do a quick and dirty hack instead.  Otherwise we just
+# end up re-implementing each distro's pidfile support...
+check_status_valgrind ()
+{
+    if pkill -0 -f "valgrind.*${ctdbd}" ; then
+       echo "ctdbd is running under valgrind..."
+       return 0
+    else
+       echo "ctdbd is not running"
+       return 1
+    fi
+}
+
+check_status ()
+{
+    # Backward compatibility.  When we arrange to pass --pidfile to
+    # ctdbd we also create the directory that will contain it.  If
+    # that directory is missing then we don't use the pidfile to check
+    # status.
+    if [ -d $(dirname "$pidfile") ] ; then
+       _pf_opt="-p $pidfile"
+    else
+       _pf_opt=""
+    fi
+
+    case "$init_style" in
+       valgrind)
+           check_status_valgrind
+           ;;
+       suse)
+           checkproc $_pf_opt "$ctdbd"
+           rc_status -v
+           ;;
+       redhat)
+           status $_pf_opt -l "ctdb" "$ctdbd"
+           ;;
+       debian)
+           status_of_proc $_pf_opt "$ctdbd" "ctdb"
+           ;;
+    esac
 }
 
 
@@ -417,14 +444,16 @@ case "$1" in
        restart
        ;;
     status)
-       status
+       check_status
        ;;
     condrestart|try-restart)
-       ctdb status > /dev/null && restart || :
+       if check_status >/dev/null ; then
+           restart
+       fi
        ;;
     cron)
        # used from cron to auto-restart ctdb
-       ctdb status > /dev/null || restart
+       check_status >/dev/null || restart
        ;;
     *)
        echo $"Usage: $0 {start|stop|restart|reload|force-reload|status|cron|condrestart|try-restart}"