From 436238cb5e5e57401e38b4ce5e62fa998def4dfe Mon Sep 17 00:00:00 2001 From: Stefano Zacchiroli Date: Fri, 16 Apr 2004 15:56:20 +0000 Subject: [PATCH] added generic daemon respawner --- helm/scripts/init.d/daemon_respawner.sh | 147 ++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100755 helm/scripts/init.d/daemon_respawner.sh diff --git a/helm/scripts/init.d/daemon_respawner.sh b/helm/scripts/init.d/daemon_respawner.sh new file mode 100755 index 000000000..7eaccee8a --- /dev/null +++ b/helm/scripts/init.d/daemon_respawner.sh @@ -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 +# +# 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 ] [-r|--request ] [-i|--interval ] [-m|--mailto ] -d|--daemon " + echo " ./daemon_respawner -d|--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 +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 + -- 2.39.2