]> matita.cs.unibo.it Git - helm.git/blob - helm/scripts/init.d/daemon_respawner.sh
- ported to typed explicit substitutions
[helm.git] / helm / scripts / init.d / daemon_respawner.sh
1 #!/bin/bash
2 #
3 # Generic respawner for daemon processes.
4 #
5 # Created:        Fri, 16 Apr 2004 17:40:36 +0200 zacchiro
6 # Last-Modified:  Fri, 16 Apr 2004 17:40:36 +0200 zacchiro
7 #
8 # by --Zack <zack@cs.unibo.it>
9 #
10 # Test to see if a daemon process (run via /etc/init.d/script) if still alive,
11 # if not it respawns it using the corresponding init script. In order to check
12 # if the daemon is still alive different predicates could be used:
13 # 1) "ps" check with its pid
14 # 2) http request to its url (if it's a web services)
15 # all the available predicated can be enable or not (command line choice), all
16 # the enabled predicates are ANDed. It's enough that one of them fails to
17 # trigger daemon respawning.
18 #
19 # This respawner is supposed to be executed by "start" target of daemon's init.d
20 # script.
21 #
22 # Sample /etc/init.d/foo script:
23
24 #   DAEMON="/usr/sbin/foo"
25 #   PIDFILE="/var/run/$DAEMON.pid"
26 #   start)
27 #       echo -n "Starting $DAEMON"
28 #       start-stop-daemon \
29 #         --start --background --pidfile $PIDFILE --make-pidfile --exec $DAEMON
30 #       echo "."
31 #       echo -n "Starting $DAEMON respawner"
32 #       /etc/init.d/daemon_respawner.sh -p $PIDFILE \ -m root@localhost \
33 #         -r http://localhost:9999/help -d `basename $0` &
34 #       echo "."
35 #       ;;
36 #   stop)
37 #       echo -n "Stopping $DAEMON respawner"
38 #       /etc/init.d/daemon_respawner.sh -d `basename $0` -s
39 #       echo "."
40 #       echo -n "Stopping $DAEMON"
41 #       start-stop-daemon --stop --pidfile $PIDFILE
42 #       rm -f $PIDFILE
43 #       echo "."
44 #       ;;
45 #   ...
46 #
47
48 # parse arguments
49 TEMP=`getopt -o p:r:d:i:m:s --long pidfile:request:daemon:interval:mailto:stop -- "$@"`
50 if [ $? != 0 ]; then
51   echo "Usage: ./daemon_respawner [-p|--pidfile <pidfile>] [-r|--request <url>] [-i|--interval <interval>] [-m|--mailto <mail>] -d|--daemon <daemon>"
52   echo "       ./daemon_respawner -d|--daemon <daemon> -s|--stop"
53   exit 1
54 fi
55 PIDFILE=""
56 REQUEST=""
57 DAEMON=""
58 INTERVAL="60"
59 MAILTO=""
60 STOP=""
61 eval set -- "$TEMP"
62 while true ; do
63   case "$1" in
64     -p|--pidfile)   PIDFILE="$2";   shift 2 ;;
65     -r|--request)   REQUEST="$2";   shift 2 ;;
66     -d|--daemon)    DAEMON="$2";    shift 2 ;;
67     -i|--interval)  INTERVAL="$2";  shift 2 ;;
68     -m|--mailto)    MAILTO="$2";    shift 2 ;;
69     -s|--stop)      STOP="yes";     shift ;;
70     --) shift; break ;;
71   esac
72 done
73 if [ -z "$DAEMON" ]; then
74   echo "No daemon provided: aborting."
75   exit 2
76 fi
77 MYPIDFILE="/var/run/$DAEMON""_respawner.pid"
78 if ! [ -z "$STOP" ]; then # stop an active respawner and exit
79   if [ -r "$MYPIDFILE" ]; then
80     kill `cat "$MYPIDFILE"`
81   fi
82   rm -f "$MYPIDFILE"
83   exit 0
84 fi
85 if [ -z "$PIDFILE" -a -z "$REQUEST" ]; then
86   echo "Neither pidfile nor request URL was provided: aborting."
87   exit 2
88 fi
89
90 TIMEOUT="5" # timeout for http requests
91
92 # usage: alert <subject> <body>
93 alert ()
94 {
95   if [ -z "$MAILTO" ]; then
96     echo "ALERT: $1"
97     echo "ALERT: $2"
98     echo
99   else
100     echo "$2" | mail -s "$1" $MAILTO
101   fi
102 }
103
104 # check if daemon is still alive
105 daemon_is_alive ()
106 {
107   IS_DEAD=""
108   if ! [ -z "$PIDFILE" ]; then  # pid check enabled
109     if ! (ps `cat $PIDFILE` &> /dev/null); then # pid is no longer alive
110       IS_DEAD="true"
111     fi
112   fi
113   if ! [ -z "$REQUEST" ]; then  # request check enabled
114     if ! (wget -T $TIMEOUT -O /dev/null "$REQUEST" &> /dev/null); then
115       # no answer
116       IS_DEAD="true"
117     fi
118   fi
119   test -z "$IS_DEAD"
120 }
121
122 # respawn daemon
123 start_daemon ()
124 {
125   rm -f "$MYPIDFILE"
126   invoke-rc.d $DAEMON stop
127   invoke-rc.d $DAEMON start &
128   exit 0  # the respawner will be restarted by daemon's init.d script
129 }
130
131 # first check
132 sleep 1
133 if ! daemon_is_alive; then
134    alert "$DAEMON failed to start :-((" "$DAEMON died during initialization :-((, enjoy debugging! :-P. Cheers."
135    exit 3
136 fi
137 # save pid
138 echo $$ > "$MYPIDFILE"
139 # continuous checks
140 while true; do
141    sleep $INTERVAL
142    if ! daemon_is_alive; then
143       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."
144       start_daemon  # performed in background
145    fi
146 done
147