]> matita.cs.unibo.it Git - helm.git/commitdiff
added generic daemon respawner
authorStefano Zacchiroli <zack@upsilon.cc>
Fri, 16 Apr 2004 15:56:20 +0000 (15:56 +0000)
committerStefano Zacchiroli <zack@upsilon.cc>
Fri, 16 Apr 2004 15:56:20 +0000 (15:56 +0000)
helm/scripts/init.d/daemon_respawner.sh [new file with mode: 0755]

diff --git a/helm/scripts/init.d/daemon_respawner.sh b/helm/scripts/init.d/daemon_respawner.sh
new file mode 100755 (executable)
index 0000000..7eaccee
--- /dev/null
@@ -0,0 +1,147 @@
+#!/bin/bash
+#
+# Generic respawner for daemon processes.
+#
+# Created:       Fri, 16 Apr 2004 17:40:36 +0200 zacchiro
+# Last-Modified:  Fri, 16 Apr 2004 17:40:36 +0200 zacchiro
+#
+# by --Zack <zack@cs.unibo.it>
+#
+# Test to see if a daemon process (run via /etc/init.d/script) if still alive,
+# if not it respawns it using the corresponding init script. In order to check
+# if the daemon is still alive different predicates could be used:
+# 1) "ps" check with its pid
+# 2) http request to its url (if it's a web services)
+# all the available predicated can be enable or not (command line choice), all
+# the enabled predicates are ANDed. It's enough that one of them fails to
+# trigger daemon respawning.
+#
+# This respawner is supposed to be executed by "start" target of daemon's init.d
+# script.
+#
+# Sample /etc/init.d/foo script:
+# 
+#   DAEMON="/usr/sbin/foo"
+#   PIDFILE="/var/run/$DAEMON.pid"
+#   start)
+#      echo -n "Starting $DAEMON"
+#      start-stop-daemon \
+#        --start --background --pidfile $PIDFILE --make-pidfile --exec $DAEMON
+#      echo "."
+#      echo -n "Starting $DAEMON respawner"
+#      /home/zacchiro/bin/daemon_respawner.sh -p $PIDFILE \ -m root@localhost \
+#        -r http://localhost:9999/bad -d `basename $0` &
+#      echo "."
+#      ;;
+#   stop)
+#      echo -n "Stopping $DAEMON respawner"
+#      /home/zacchiro/bin/daemon_respawner.sh -d `basename $0` -s
+#      echo "."
+#      echo -n "Stopping $DAEMON"
+#      start-stop-daemon --stop --pidfile $PIDFILE
+#      rm -f $PIDFILE
+#      echo "."
+#      ;;
+#   ...
+#
+
+# parse arguments
+TEMP=`getopt -o p:r:d:i:m:s --long pidfile:request:daemon:interval:mailto:stop -- "$@"`
+if [ $? != 0 ]; then
+  echo "Usage: ./daemon_respawner [-p|--pidfile <pidfile>] [-r|--request <url>] [-i|--interval <interval>] [-m|--mailto <mail>] -d|--daemon <daemon>"
+  echo "       ./daemon_respawner -d|--daemon <daemon> -s|--stop"
+  exit 1
+fi
+PIDFILE=""
+REQUEST=""
+DAEMON=""
+INTERVAL="60"
+MAILTO=""
+STOP=""
+eval set -- "$TEMP"
+while true ; do
+  case "$1" in
+    -p|--pidfile)   PIDFILE="$2";   shift 2 ;;
+    -r|--request)   REQUEST="$2";   shift 2 ;;
+    -d|--daemon)    DAEMON="$2";    shift 2 ;;
+    -i|--interval)  INTERVAL="$2";  shift 2 ;;
+    -m|--mailto)    MAILTO="$2";    shift 2 ;;
+    -s|--stop)     STOP="yes";     shift ;;
+    --) shift; break ;;
+  esac
+done
+if [ -z "$DAEMON" ]; then
+  echo "No daemon provided: aborting."
+  exit 2
+fi
+MYPIDFILE="/var/run/$DAEMON""_respawner.pid"
+if ! [ -z "$STOP" ]; then # stop an active respawner and exit
+  if [ -r "$MYPIDFILE" ]; then
+    kill `cat "$MYPIDFILE"`
+  fi
+  rm -f "$MYPIDFILE"
+  exit 0
+fi
+if [ -z "$PIDFILE" -a -z "$REQUEST" ]; then
+  echo "Neither pidfile nor request URL was provided: aborting."
+  exit 2
+fi
+
+TIMEOUT="5" # timeout for http requests
+
+# usage: alert <subject> <body>
+alert ()
+{
+  if [ -z "$MAILTO" ]; then
+    echo "ALERT: $1"
+    echo "ALERT: $2"
+    echo
+  else
+    echo "$2" | mail -s "$1" $MAILTO
+  fi
+}
+
+# check if daemon is still alive
+daemon_is_alive ()
+{
+  IS_DEAD=""
+  if ! [ -z "$PIDFILE" ]; then # pid check enabled
+    if ! (ps `cat $PIDFILE` &> /dev/null); then        # pid is no longer alive
+      IS_DEAD="true"
+    fi
+  fi
+  if ! [ -z "$REQUEST" ]; then # request check enabled
+    if ! (wget -T $TIMEOUT -O /dev/null "$REQUEST" &> /dev/null); then
+      # no answer
+      IS_DEAD="true"
+    fi
+  fi
+  test -z "$IS_DEAD"
+}
+
+# respawn daemon
+start_daemon ()
+{
+  rm -f "$MYPIDFILE"
+  invoke-rc.d $DAEMON stop
+  invoke-rc.d $DAEMON start &
+  exit 0  # the respawner will be restarted by daemon's init.d script
+}
+
+# first check
+sleep 1
+if ! daemon_is_alive; then
+   alert "$DAEMON failed to start :-((" "$DAEMON died during initialization :-((, enjoy debugging! :-P. Cheers."
+   exit 3
+fi
+# save pid
+echo $$ > "$MYPIDFILE"
+# continuous checks
+while true; do
+   sleep $INTERVAL
+   if ! daemon_is_alive; then
+      alert "$DAEMON died :-(, restarting it ..." "$DAEMON died miserably :-(. I'm going to try restarting it, you will receive an additional mail in case of failure. Cheers."
+      start_daemon  # performed in background
+   fi
+done
+