ctdb-scripts: Split CTDB configuration loading
[samba.git] / ctdb / config / ctdbd_wrapper
index dd9d66f4956ccca88b029abf653d43d53a6baa23..8f3c6cb4d2eb5ae03c105959d7fad942d27d5e3c 100755 (executable)
@@ -4,79 +4,63 @@
 
 usage ()
 {
-    echo "usage: ctdbd_wrapper <pidfile> { start | stop }"
+    echo "usage: ctdbd_wrapper { start | stop }"
     exit 1
 }
 
-[ $# -eq 2 ] || usage
+[ $# -eq 1 ] || usage
 
-pidfile="$1"
-action="$2"
+action="$1"
 
 ############################################################
 
-[ -n "$CTDB_BASE" ] || export CTDB_BASE="/etc/ctdb"
+if [ -z "$CTDB_BASE" ] ; then
+    export CTDB_BASE="/usr/local/etc/ctdb"
+fi
 
 . "${CTDB_BASE}/functions"
-loadconfig "ctdb"
 
-[ -n "$CTDB_SOCKET" ] && export CTDB_SOCKET
+loadconfig
 
-ctdbd="${CTDBD:-/usr/sbin/ctdbd}"
+ctdbd="${CTDBD:-/usr/local/sbin/ctdbd}"
 
 ############################################################
 
-# ctdbd_is_running()
-
-# 1. Check if ctdbd is running.
-#    - If the PID file is being used then, if the PID file is present,
-#      ctdbd is only considered to running if the PID in the file is
-#      active.
-#    - If the PID file is not being used (i.e. we're upgrading from a
-#      version that doesn't support it) then the presence of any ctdbd
-#      processes is enough proof.
-
-# 2. Print a comma-separated list of PIDs that can be
-#    used with "pkill -s".
-#    - If the PID file is being used then this is just the PID in that
-#      file.  This also happens to be the session ID, so can be used
-#      to kill all CTDB processes.
-#    - If the PID file is not being used (i.e. upgrading) then this is
-#      just any ctdbd processes that are running.  Hopefully one of
-#      them is the session ID so that it can be used to kill all CTDB
-#      processes.
-
-# Combining these 2 checks is an optimisation to avoid potentially
-# running too many pgrep/pkill processes on an already loaded system.
-# Trawling through /proc/ can be very expensive.
-
-ctdbd_is_running ()
+# If necessary, mount volatile database directory on tmpfs
+dbdir_tmpfs_start ()
 {
-    # If the directory for the PID file exists then respect the
-    # existence of a PID file.
-    _pidfile_dir=$(dirname "$pidfile")
-    if [ -d "$_pidfile_dir" ] ; then
-       if read _pid 2>/dev/null <"$pidfile" ; then
-           echo "$_pid"
-
-           # Return value of kill is used
-           kill -0 $_pid 2>/dev/null
-       else
-           # Missing/empty PID file
-           return 1
-       fi
+    if [ -z "$CTDB_DBDIR_TMPFS_OPTIONS" ] ; then
+       return
+    fi
+
+    # Shortcut for readability
+    _opts="$CTDB_DBDIR_TMPFS_OPTIONS"
+
+    mkdir -p "$CTDB_DBDIR" || exit $?
+
+    # If already mounted then remount, otherwise mount
+    if findmnt -t tmpfs "$CTDB_DBDIR" >/dev/null ; then
+       mount -t tmpfs -o "remount,$_opts" none "$CTDB_DBDIR" || \
+           exit $?
     else
-       if _pid=$(pgrep -f "${ctdbd}\>") ; then
-           echo $_pid | sed -e 's@ @,@g'
-           return 0
-       else
-           return 1
-       fi
+       mount -t tmpfs -o "$_opts" none "$CTDB_DBDIR" || exit $?
     fi
 }
 
-############################################################
+# If necessary, unmount volatile database tmpfs directory on exit
+dbdir_tmpfs_stop ()
+{
+    if [ -z "$CTDB_DBDIR_TMPFS_OPTIONS" ] ; then
+       return
+    fi
+
+    if [ -d "$CTDB_DBDIR" ] && findmnt -t tmpfs "$CTDB_DBDIR" >/dev/null ; then
+       umount "$CTDB_DBDIR"
+    fi
+}
 
+# Only the nested function references its arguments
+# shellcheck disable=SC2120
 build_ctdb_options ()
 {
     ctdb_options=""
@@ -108,18 +92,12 @@ build_ctdb_options ()
     fi
     maybe_set "--reclock"                "$CTDB_RECOVERY_LOCK"
 
-    maybe_set "--pidfile"                "$pidfile"
-
     # build up ctdb_options variable from optional parameters
     maybe_set "--logging"                "$CTDB_LOGGING"
-    maybe_set "--nlist"                  "$CTDB_NODES"
-    maybe_set "--socket"                 "$CTDB_SOCKET"
-    maybe_set "--public-addresses"       "$CTDB_PUBLIC_ADDRESSES"
-    maybe_set "--public-interface"       "$CTDB_PUBLIC_INTERFACE"
+    maybe_set "--listen"                 "$CTDB_NODE_ADDRESS"
     maybe_set "--dbdir"                  "$CTDB_DBDIR"
     maybe_set "--dbdir-persistent"       "$CTDB_DBDIR_PERSISTENT"
     maybe_set "--dbdir-state"            "$CTDB_DBDIR_STATE"
-    maybe_set "--event-script-dir"       "$CTDB_EVENT_SCRIPT_DIR"
     maybe_set "--transport"              "$CTDB_TRANSPORT"
     maybe_set "-d"                       "$CTDB_DEBUGLEVEL"
     maybe_set "--notification-script"    "$CTDB_NOTIFY_SCRIPT"
@@ -127,7 +105,7 @@ build_ctdb_options ()
     maybe_set "--start-as-stopped "      "$CTDB_START_AS_STOPPED"     "yes"
     maybe_set "--no-recmaster"           "$CTDB_CAPABILITY_RECMASTER" "no"
     maybe_set "--no-lmaster"             "$CTDB_CAPABILITY_LMASTER"   "no"
-    maybe_set "--lvs --single-public-ip" "$CTDB_LVS_PUBLIC_IP"
+    maybe_set "--nosetsched"             "$CTDB_NOSETSCHED"           "yes"
     maybe_set "--script-log-level"       "$CTDB_SCRIPT_LOG_LEVEL"
     maybe_set "--max-persistent-check-errors" "$CTDB_MAX_PERSISTENT_CHECK_ERRORS"
 }
@@ -135,51 +113,38 @@ build_ctdb_options ()
 export_debug_variables ()
 {
     [ -n "$CTDB_DEBUG_HUNG_SCRIPT" ] && export CTDB_DEBUG_HUNG_SCRIPT
-    [ -n "$CTDB_EXTERNAL_TRACE" ] && export CTDB_EXTERNAL_TRACE
     [ -n "$CTDB_DEBUG_LOCKS" ] && export CTDB_DEBUG_LOCKS
 }
 
-kill_ctdbd ()
-{
-    _session="$1"
-
-    if [ -n "$_session" ] ; then
-       pkill -9 -s "$_session" 2>/dev/null
-    fi
-    rm -f "$pidfile"
-}
-
 ############################################################
 
 start()
 {
-    if _session=$(ctdbd_is_running) ; then
-       echo $"CTDB is already running"
-       return 0
-    fi
-
-    # About to start new $ctdbd.  The main daemon is not running but
-    # there may still be other processes around, so do some cleanup.
-    # Note that starting ctdbd below will destroy the Unix domain
-    # socket, so any processes that aren't yet completely useless soon
-    # will be, so this can really do no harm.
-    kill_ctdbd "$_session"
+    dbdir_tmpfs_start
 
+    # build_ctdb_options() takes no arguments
+    # shellcheck disable=SC2119
     build_ctdb_options
 
     export_debug_variables
 
+    # Explicitly trying to disable core files, no other way
+    # shellcheck disable=SC2039
     if [ "$CTDB_SUPPRESS_COREFILE" = "yes" ]; then
        ulimit -c 0
     else
        ulimit -c unlimited
     fi
 
-    mkdir -p $(dirname "$pidfile")
+    # Unsupported option easily avoided by not using configuration variable
+    # shellcheck disable=SC2039
+    if [ -n "$CTDB_MAX_OPEN_FILES" ]; then
+       ulimit -n "$CTDB_MAX_OPEN_FILES"
+    fi
 
     if [ -n "$CTDB_VALGRIND" -a "$CTDB_VALGRIND" != "no" ] ; then
        if [ "$CTDB_VALGRIND" = "yes" ] ; then
-           ctdbd="valgrind -q --log-file=/var/log/ctdb_valgrind ${ctdbd}"
+           ctdbd="valgrind -q --log-file=/usr/local/var/log/ctdb_valgrind ${ctdbd}"
        else
            ctdbd="${CTDB_VALGRIND} ${ctdbd}"
        fi
@@ -187,6 +152,9 @@ start()
     fi
 
     case "$CTDB_LOGGING" in
+       syslog:udp|syslog:udp-rfc5424)
+           logger -t ctdbd "CTDB is being run with ${CTDB_LOGGING}.  If nothing is logged then check your syslogd configuration"
+           ;;
        syslog|syslog:*) : ;;
        file:*)
            logger -t ctdbd "CTDB is being run without syslog enabled.  Logs will be in ${CTDB_LOGGING#file:}"
@@ -198,70 +166,40 @@ start()
     eval "$ctdbd" "$ctdb_options" || return 1
 
     # Wait until ctdbd has started and is ready to respond to clients.
-    _pid=""
     _timeout="${CTDB_STARTUP_TIMEOUT:-10}"
     _count=0
-    while [ $_count -lt $_timeout ] ; do
-       # If we don't have the PID then try to read it.
-       [ -n "$_pid" ] || read _pid 2>/dev/null <"$pidfile"
-
-       # If we got the PID but the PID file has gone or the process
-       # is no longer running then stop waiting... CTDB is dead.
-       if [ -n "$_pid" ] ; then
-           if [ ! -e "$pidfile" ] || ! kill -0 "$_pid" 2>/dev/null ; then
-               echo "CTDB exited during initialisation - check logs."
-               kill_ctdbd "$_pid"
-               drop_all_public_ips >/dev/null 2>&1
-               return 1
-           fi
-
-           if ctdb runstate first_recovery startup running >/dev/null 2>&1 ; then
-               return 0
-           fi
+    while [ "$_count" -lt "$_timeout" ] ; do
+       if $CTDB runstate first_recovery startup running >/dev/null 2>&1 ; then
+           return 0
        fi
 
-       _count=$(($_count + 1))
+       _count=$((_count + 1))
        sleep 1
     done
 
-    echo "Timed out waiting for initialisation - check logs - killing CTDB"
-    kill_ctdbd "$_pid"
+    echo "Timed out waiting for initialisation - check logs"
+    # Attempt a shutdown just in case things are still running
+    $CTDB shutdown >/dev/null 2>&1
     drop_all_public_ips >/dev/null 2>&1
     return 1
 }
 
 stop()
 {
-    if ! _session=$(ctdbd_is_running) ; then
-       echo "CTDB is not running"
-       return 0
-    fi
-
-    ctdb shutdown
+       $CTDB shutdown
 
-    # Wait for remaining CTDB processes to exit...
-    _timeout=${CTDB_SHUTDOWN_TIMEOUT:-30}
-    _count=0
-    while [ $_count -lt $_timeout ] ; do
-       pkill -0 -s "$_session" 2>/dev/null || return 0
-
-       _count=$(($_count + 1))
-       sleep 1
-    done
-
-    echo "Timed out waiting for CTDB to shutdown.  Killing CTDB processes."
-    kill_ctdbd "$_session"
-    drop_all_public_ips >/dev/null 2>&1
-
-    sleep 1
+       # The above command is important and needs to stand out, so
+       # post-check exit status
+       # shellcheck disable=SC2181
+       if [ $? -ne 0 ] ; then
+               echo "Error while shutting down CTDB"
+               drop_all_public_ips >/dev/null 2>&1
+               return 1
+       fi
 
-    if pkill -0 -s "$_session" ; then
-       # If SIGKILL didn't work then things are bad...
-       echo "Failed to kill all CTDB processes.  Giving up."
-       return 1
-    fi
+       dbdir_tmpfs_stop
 
-    return 0
+       return 0
 }
 
 ############################################################