From: Alan T. DeKok Date: Tue, 5 May 2009 19:30:38 +0000 (+0200) Subject: Update to do a LOT more checking, and to NOT send email. X-Git-Tag: release_2_1_7~178 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=31040f7ae46dba085adf9bc8468d8b154d9544df;p=thirdparty%2Ffreeradius-server.git Update to do a LOT more checking, and to NOT send email. Sending email is bad, as it wasn't rate limited. This new script checks for a lot more conditions, including HUP and TERM sent to the script itself. --- diff --git a/scripts/radwatch.in b/scripts/radwatch.in old mode 100755 new mode 100644 index 854324b8a11..6f392d4cb5f --- a/scripts/radwatch.in +++ b/scripts/radwatch.in @@ -1,60 +1,162 @@ -#! /bin/sh +#!/bin/sh +###################################################################### # -# radwatch Script to watch RADIUS. Sends mail to root and -# restarts radiusd when it dies [which ofcourse -# never happens :)] +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. # -# WARNING! This script SHOULD NOT BE USED! It's only here for historical -# purposes, and WILL be deleted in a future version of the -# the server. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. # -# If you want to watch and re-start the server, we recommend -# reading the file doc/supervise-radiusd.txt +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA # +# Copyright (C) 2009 Network RADIUS SARL # -# Version: $Id$ +###################################################################### # +# radwatch - Start the radius daemon and restart upon crash. +# +# It also catches signals sent to it, and then re-sends those signals +# to the radius server it is watching. +# +# If you want to watch and re-start the server, we recommend +# reading the file doc/supervise-radiusd.txt +# prefix=@prefix@ exec_prefix=@exec_prefix@ sbindir=@sbindir@ localstatedir=@localstatedir@ logdir=@logdir@ rundir=${localstatedir}/run/radiusd +sysconfdir=@sysconfdir@ +pid_file=${rundir}/radiusd.pid +log_file=${logdir}/radiusd_safe.log -MAILTO=root RADIUSD=$sbindir/radiusd +RADDBDIR=${sysconfdir}/raddb + +# +# Allow "radiusd_safe -X" for testing the radiusd_safe functionality. +# +ARGS="$@" -exec >> $logdir/radwatch.log 2>&1 +test -f $RADIUSD || exit 0 +test -f $RADDBDIR/radiusd.conf || exit 0 -# get the path to the radiusd -if [ "$1" ] && [ -x "$1" ] +# +# This simplifies the script, and avoids most issues with (say) +# Debian re-naming "radiusd" to "freeradius". +# +name=`basename $RADIUSD` + +ulimit -c unlimited + +# +# See if the PID file exists. It might have been left over after +# a crash, or it might be because the RADIUS server is still running. +# +if test -f $pid_file then - RADIUSD=$1 - shift + PID=`cat $pid_file` + # + # Check if the process exists, AND if it has the right name + # + if ps -p $PID | grep $name > /dev/null + then + echo "`date +'%a %b %e %H:%M:%S %Y'` : Fatal: A $name process already exists at PID $PID. We cannot start another one." >> $log_file + echo "A $name process already exists" + exit 1 + fi + + # + # A RADIUS server doesn't exist. Delete the stale PID file. + # + rm -f $pid_file + if test -f $pid_file + then + echo "`date +'%a %b %e %H:%M:%S %Y'` : Fatal: Cannot remove the pid file: $pid_file" >> $log_file + echo "Fatal error: Cannot remove the pid file: $pid_file" + echo "Please remove it manually and start $0 again" + echo "$name daemon not started" + exit 1 + fi fi -cd $logdir -[ -d $logdir/radacct ] && cd $logdir/radacct -ulimit -c unlimited +# +# Loop forever, or until we're told to exit via a signal. +# +while : +do + mysig= + trap 'mysig=yes' HUP TERM INT QUIT TSTP + + eval "$RADIUSD -f $ARGS < /dev/null >> $log_file 2>&1 &" + PID=$! + + if test "$?" != "0" + then + echo "Failed to start $name. See $log_file for details" + echo "$name daemon not started" + exit 1 + fi + + echo $PID > $pid_file + + # + # Wait for the process to exit. + # + wait $PID + code=$? + + case "$code" in + 0) + echo "`date +'%a %b %e %H:%M:%S %Y'` : Info: $name exited normally. Exiting" | tee -a $log_file + break + ;; + + 127) + echo "`date +'%a %b %e %H:%M:%S %Y'` : Info: $name exited unexpectedly. Restarting it." | tee -a $log_file + + # + # If there is some kind of issue, we don't want to start + # a fork bomb. + # + sleep 1 + ;; + + *) + # + # The server exited of its own accord. + # + if test "$code" -lt 128 + then + echo "`date +'%a %b %e %H:%M:%S %Y'` : Info: $name exited unexpectedly on exit code $code. Restarting it." | tee -a $log_file + sleep 1 + else + sig=`expr $code - 128` + + # + # Was the signal sent to us, or to the child process? + # + if test "$mysig" = "yes" + then + echo "`date +'%a %b %e %H:%M:%S %Y'` : Info: Caught signal $sig: Signalling $name to exit." | tee -a $log_file + kill -`expr $code - 128` $PID + break + else + echo "`date +'%a %b %e %H:%M:%S %Y'` : Info: $name exited unexpectedly on signal $sig. Restarting it." | tee -a $log_file + sleep 1 + fi + fi + ;; + esac +done -( - trap 'echo `date`: exit; kill `cat $rundir/radiusd.pid`; exit 0' TERM - trap "" HUP TSTP - - while : - do - # Use `wait', otherwise the trap doesn't work. - $RADIUSD -f $* & - echo "$!" > $rundir/radiusd.pid - wait - exec >> $logdir/radwatch.log 2>&1 - echo "`date`: Radius died, restarting.." - date | mail -s "Radius died, restarting.." $MAILTO - sleep 10 - done -) & - -echo "$!" > $rundir/radwatch.pid - -sleep 1 +rm -f $pid_file +exit 0