2 ######################################################################
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 2 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 # Copyright (C) 2009 Network RADIUS SARL <info@networkradius.com>
20 ######################################################################
22 # radwatch - Start the radius daemon and restart upon crash.
24 # It also catches signals sent to it, and then re-sends those signals
25 # to the radius server it is watching.
27 # If you want to watch and re-start the server, we recommend
28 # reading the file doc/supervise-radiusd.txt
31 # This simplifies the script, and avoids most issues with (say)
32 # Debian re-naming "radiusd" to "freeradius".
37 exec_prefix=@exec_prefix@
39 localstatedir=@localstatedir@
41 rundir=${localstatedir}/run/${name}
42 sysconfdir=@sysconfdir@
43 pid_file=${rundir}/${name}.pid
44 log_file=${logdir}/${name}_safe.log
47 # Figure out what arguments to pass tail
50 echo foo | ${tail}1 > /dev/null 2>&1
56 RADIUSD=$sbindir/${name}
57 RADDBDIR=${sysconfdir}/raddb
60 # If you want to send email, define this field to be an email address.
61 # This part of the functionality hasn't been well tested, so please
62 # test it before putting it into production.
64 # It also presumes that you have a functioning mail system on
65 # the maching running RADIUS. You will need to check that the
66 # "mail" command exists, and sends mail to the address below, e.g.:
68 # echo test | mail -s "Testing" $MAILTO
70 # If you receive the message, then enable MAILTO. Otherwise, fix
71 # your mail system so that it delivers mail.
76 # Allow "radiusd_safe -X" for testing the radiusd_safe functionality.
80 test -f $RADIUSD || exit 0
81 test -f $RADDBDIR/radiusd.conf || exit 0
86 # See if the PID file exists. It might have been left over after
87 # a crash, or it might be because the RADIUS server is still running.
93 # Check if the process exists, AND if it has the right name
95 if ps -p $PID | grep $name > /dev/null
97 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
98 echo "A $name process already exists"
103 # A RADIUS server doesn't exist. Delete the stale PID file.
108 echo "`date +'%a %b %e %H:%M:%S %Y'` : Fatal: Cannot remove the pid file: $pid_file" >> $log_file
109 echo "Fatal error: Cannot remove the pid file: $pid_file"
110 echo "Please remove it manually and start $0 again"
111 echo "$name daemon not started"
124 echo $$ > ${rundir}/${name}_safe.pid
127 # Loop forever, or until we're told to exit via a signal.
132 # The first time around, just start the server.
133 # After that, see if we are re-starting in the same second
134 # as the last time. If so, sleep for a second. Otherwise,
135 # if we're not starting in the same second, then just restart
138 # This helps prevent CPU spikes when something goes catastrophically
139 # wrong, and the server re-starts continuously. (e.g. disk full, etc.)
141 now_s=`date +'%a %b %e %H:%M:%S %Y'`
142 if test "$started" != "0"
144 # Send mail when the server starts
145 if test "$MAILTO" != ""
147 # don't print minutes and seconds: cheap way
148 # of sending email only once an hour.
149 now=`date +'%a %b %e %H %Y'`
150 restarts=`expr $restarts + 1`
152 # send email the first time it restarts
153 if test "$last_email" = "0"
155 cat | mail -s "ERROR - $name died, restarting.." $MAILTO <<EOF
156 $name has restarted unexpectedly at $now
158 See $log_file for details. Last 20 lines are:
160 ----------------------------------------------------------------------
161 `${tail}20 $log_file`
166 # Send email only once every hour (or so)
167 if test "$now" != "$last_email"
169 cat | mail -s "ERROR - $name died, restarting.." $MAILTO <<EOF
170 $name has restarted $restarts times since last email at $last_email
172 See $log_file for details. Last 100 lines are:
174 ----------------------------------------------------------------------
175 `${tail}100 $log_file`
183 if test "$started" = "$now_s"
185 # Allow us to be killed
186 trap - HUP INT QUIT TERM TSTP
199 eval "$RADIUSD -f $ARGS < /dev/null >> $log_file 2>&1 &"
204 echo "Failed to start $name. See $log_file for details"
205 echo "$name daemon not started"
209 echo $PID > $pid_file
212 # Wait for the process to exit.
218 # On *BSD and Linux, sending *us* a signal results in "wait" returning
219 # with 128+sig. On Solaris, it results in "wait" returning with "0".
221 # If this happens, we reset our expectations here so that the code
222 # below will work correctly.
224 if test "$code" = "0"
226 if test "$mysig" != ""
228 code=`expr $mysig + 128`
234 echo "`date +'%a %b %e %H:%M:%S %Y'` : Info: $name exited normally. Exiting" | tee -a $log_file
239 echo "`date +'%a %b %e %H:%M:%S %Y'` : Info: $name exited unexpectedly. Restarting it." | tee -a $log_file
244 # The server exited of its own accord.
246 if test "$code" -lt 128
248 echo "`date +'%a %b %e %H:%M:%S %Y'` : Info: $name exited unexpectedly on exit code $code. Restarting it." | tee -a $log_file
250 sig=`expr $code - 128`
253 # Was the signal sent to us, or to the child process?
255 if test "$mysig" != ""
257 echo "`date +'%a %b %e %H:%M:%S %Y'` : Info: Caught signal $sig: Signalling $name to exit." | tee -a $log_file
261 echo "`date +'%a %b %e %H:%M:%S %Y'` : Info: $name exited unexpectedly on signal $sig. Restarting it." | tee -a $log_file
268 rm -f $pid_file ${rundir}/${name}_safe.pid