#! /bin/sh
#
# Davor Ocelic, docelic@mail.inet.hr, Jun 15, 2004.
#
# /etc/init.d/testnet script to test network connectivity under Debian GNU.
#
# This script was written to help in maintenance of The Internet Hosting 
# Cooperative machines ( http://www.hcoop.net/ ).
# An article describing the whole procedure is at 
# http://techpubs.spinlocksolutions.com/debian/remote-reboot.html
#
#
# We ping a host to see if the network link works. If we're unsuccessful
# even after 2 passes - we reboot. (at that point the bootloader configuration
# should handle booting the old, known-to-work kernel again).
#
# It should be scheduled to run after /etc/init.d/networking , here's how:
# update-rc.d testnet start 40 S .
#
# To disable:
# update-rc.d -f testnet remove
#
# NOTES:
# a) CALL_BOOTLOADER=1 is useful if your new kernel is installed as /vmlinuz,
#    and the good one was renamed to /vmlinuz.old (Linux -> LinuxOLD). But this
#    can be dicey, better use /vmlinuz.new to test the new kernel.
#

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/bin/ping
NAME=ping
DESC="network connectivity test"

TESTHOST=216.239.37.99      # **IMPORTANT** one of google IPs to ping

RETRY=30                    # time in seconds before we retry for the 2nd time
REBOOT=1                    # really reboot if connectivity test fails?
USE_SYSLOG=0                # make sure syslogd *is running* if you use this
SYSLOG="-i -p local5.crit"  # /usr/bin/logger options
CMDLINE=/proc/cmdline       # access to cmdline boot arguments
NEW_KERNEL_ONLY=1           # will run only if 'newkernel' boot arg present
CALL_BOOTLOADER=0           # free to call bootloader? (say, lilo)
SAFE_IMAGE=LinuxOLD         # which image to lilo -R before reboot on failure

# If you don't want to bother with determining paths, simply put
# definitions like logger=logger, ping=ping, etc..
logger=/usr/bin/logger
ping=/bin/ping
lilo=/sbin/lilo
reboot=/sbin/reboot
grep=/bin/grep

test -x $DAEMON || exit 0
if test "$TESTNET_PASS2" == "1"; then pass=2; else pass=1; fi

#set -x

# The reboot routine
try_reboot() {
	if test "$REBOOT" == "1"; then
		if test "$CALL_BOOTLOADER" == 1; then
			$lilo -R "$SAFE_IMAGE"
		fi
		$reboot
	fi
}


case "$1" in
  start)

	# Is it the right time to start?
	if test "$TESTNET_FORCE_RUN" != 1; then
		if test "$NEW_KERNEL_ONLY" == "1"; then
			$grep newkernel $CMDLINE > /dev/null
			if test "$?" != 0; then
				if test "$USE_SYSLOG" == 1; then
					$logger $SYSLOG -- "TESTNET skipping, done"
				fi
				echo "Skipping $DESC: (not a new kernel)."
				exit 0
			fi
		fi
	fi

	# Let's roll
	echo -n "Starting $DESC: $NAME/pass$pass"

	$ping -c 5 $TESTHOST >& /dev/null
	result="$?"

	if test "$result" == "0"; then     # OK
		if test "$USE_SYSLOG" == 1; then
			$logger $SYSLOG -- "TESTNET PASS$pass/2 OK, done"
		fi
		echo " OK, done."
	
	else                               # PROBLEM
		if test "$result" == "1"; then msg="no_replies"
		elif test "$result" == "2"; then msg="nonexistant_testhost"
		else msg="unknown problem"
		fi

		echo -n " FAILED, "
		if test "$TESTNET_PASS2" == "1"; then
			if test "$USE_SYSLOG" == 1; then
				$logger $SYSLOG -- "TESTNET PASS2/2 FAILED ($msg), rebooting"
			fi
			echo "rebooting."
			try_reboot
		else
			
			if test "$USE_SYSLOG" == 1; then
				$logger $SYSLOG -- "TESTNET PASS1/2 FAILED ($msg), retrying in $RETRY secs"
			fi
			echo "retrying in $RETRY secs."
			sleep $RETRY
			export TESTNET_PASS2=1
			/etc/init.d/testnet start
		fi
	fi

	;;
  stop|reload|restart)
	#echo -n "Restarting $DESC: $NAME"
	#echo "."
	;;
	force-start|force-reload|force-restart)
	export TESTNET_FORCE_RUN=1
	/etc/init.d/testnet start
	;;
  *)
	N=/etc/init.d/$NAME
	echo "Usage: $N {start,force-start}" >&2
	exit 1
	;;
esac

exit 0

