# reading the file doc/supervise-radiusd.txt
#
+# This simplifies the script, and avoids most issues with (say)
+# Debian re-naming "radiusd" to "freeradius".
+#
+name=radiusd
+
prefix=@prefix@
exec_prefix=@exec_prefix@
sbindir=@sbindir@
localstatedir=@localstatedir@
logdir=@logdir@
-rundir=${localstatedir}/run/radiusd
+rundir=${localstatedir}/run/${name}
sysconfdir=@sysconfdir@
-pid_file=${rundir}/radiusd.pid
-log_file=${logdir}/radiusd_safe.log
+pid_file=${rundir}/${name}.pid
+log_file=${logdir}/${name}_safe.log
-RADIUSD=$sbindir/radiusd
+#
+# Figure out what arguments to pass tail
+#
+tail="tail -n "
+echo foo | ${tail}1 > /dev/null 2>&1
+if test "$?" != "0"
+then
+ tail="tail -"
+fi
+
+RADIUSD=$sbindir/${name}
RADDBDIR=${sysconfdir}/raddb
#
+# If you want to send email, define this field to be an email address.
+# This part of the functionality hasn't been well tested, so please
+# test it before putting it into production.
+#
+# It also presumes that you have a functioning mail system on
+# the maching running RADIUS. You will need to check that the
+# "mail" command exists, and sends mail to the address below, e.g.:
+#
+# echo test | mail -s "Testing" $MAILTO
+#
+# If you receive the message, then enable MAILTO. Otherwise, fix
+# your mail system so that it delivers mail.
+#
+MAILTO=
+
+#
# Allow "radiusd_safe -X" for testing the radiusd_safe functionality.
#
ARGS="$@"
test -f $RADIUSD || exit 0
test -f $RADDBDIR/radiusd.conf || exit 0
-#
-# This simplifies the script, and avoids most issues with (say)
-# Debian re-naming "radiusd" to "freeradius".
-#
-name=`basename $RADIUSD`
-
ulimit -c unlimited
#
fi
started=0
+restarts=0
+last_email=0
+now=0
+
+#
+# Save our PID.
+#
+echo $$ > ${rundir}/${name}_safe.pid
#
# Loop forever, or until we're told to exit via a signal.
#
while :
do
- mysig=
- trap 'mysig=yes' HUP TERM INT QUIT TSTP
-
#
# The first time around, just start the server.
# After that, see if we are re-starting in the same second
# This helps prevent CPU spikes when something goes catastrophically
# wrong, and the server re-starts continuously. (e.g. disk full, etc.)
#
+ now_s=`date +'%a %b %e %H:%M:%S %Y'`
if test "$started" != "0"
then
- if test "$started" = `date +"%s"`
+ # Send mail when the server starts
+ if test "$MAILTO" != ""
then
+ # don't print minutes and seconds: cheap way
+ # of sending email only once an hour.
+ now=`date +'%a %b %e %H %Y'`
+ restarts=`expr $restarts + 1`
+
+ # send email the first time it restarts
+ if test "$last_email" = "0"
+ then
+ cat | mail -s "ERROR - $name died, restarting.." $MAILTO <<EOF
+$name has restarted unexpectedly at $now
+
+See $log_file for details. Last 20 lines are:
+
+----------------------------------------------------------------------
+`${tail}20 $log_file`
+EOF
+ last_email="$now"
+ restarts=0
+ else
+ # Send email only once every hour (or so)
+ if test "$now" != "$last_email"
+ then
+ cat | mail -s "ERROR - $name died, restarting.." $MAILTO <<EOF
+$name has restarted $restarts times since last email at $last_email
+
+See $log_file for details. Last 100 lines are:
+
+----------------------------------------------------------------------
+`${tail}100 $log_file`
+EOF
+ last_email="$now"
+ restarts=0
+ fi
+ fi
+ fi
+
+ if test "$started" = "$now_s"
+ then
+ # Allow us to be killed
+ trap - HUP INT QUIT TERM TSTP
sleep 1
fi
fi
- started=`date +"%s"`
+ started="$now_s"
+
+ mysig=
+ trap 'mysig=1' HUP
+ trap 'mysig=2' INT
+ trap 'mysig=3' QUIT
+ trap 'mysig=15' TERM
+ trap 'mysig=18' TSTP
eval "$RADIUSD -f $ARGS < /dev/null >> $log_file 2>&1 &"
PID=$!
#
wait $PID
code=$?
-
+
+ #
+ # On *BSD and Linux, sending *us* a signal results in "wait" returning
+ # with 128+sig. On Solaris, it results in "wait" returning with "0".
+ #
+ # If this happens, we reset our expectations here so that the code
+ # below will work correctly.
+ #
+ if test "$code" = "0"
+ then
+ if test "$mysig" != ""
+ then
+ code=`expr $mysig + 128`
+ fi
+ fi
+
case "$code" in
0)
echo "`date +'%a %b %e %H:%M:%S %Y'` : Info: $name exited normally. Exiting" | tee -a $log_file
#
# Was the signal sent to us, or to the child process?
#
- if test "$mysig" = "yes"
+ if test "$mysig" != ""
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
+ kill -$sig $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
esac
done
-rm -f $pid_file
+rm -f $pid_file ${rundir}/${name}_safe.pid
exit 0