it-artikel:safe-reboot.sh-script-zum-sicheren-rebooten-eines-servers-ohne-das-man-von-einem-ungeplanten-fsck-ueberrascht-wird

safe-reboot.sh - Script zum sicheren Rebooten eines Servers ohne das man von einem ungeplanten fsck überrascht wird

Wer kennt das nicht? Man will “mal eben schnell” nach einem erfolgreich durchgeführten Sicherheitsupdate den für alle Anwender so wichtigen Fileserver rebooten, hat die Filesystem Parameter nicht beachtet und landet ungeplant beim nächsten Bootvorgang in einem womöglich stunden lang laufenden fsck über diverse Terrabyte Volumes. Ärgerlich wenn man zuvor den Benutzern noch mitgeteilt hat dass der Server “nur kurz für 15 Minuten” ausfallen würde :) .

Abhilfe kann dieses Script schaffen. Ich habe es eines Tages auf Grund diese Problematiken entwickelt und seither wird es bei uns regelmäßig eingesetzt.

Anders als “reboot” geht “safe-reboot.sh” hin und überprüft zunächst auf allen aktuell gemounteten ext2/ext3/ext4 Filesystemen genau die FS-Parameter welche beim nächsten Reboot zu einem fsck führen könnten. Nämlich Mount count und Next check after. Sind diese noch im “unkritischen Bereich” so führt das Script ohne weiteres zutun des Admins nach 10 Sekunden einen “normalen reboot” durch.

Wurde hingegen festgestellt das ein Volume inzw. oder innerhalb der nächsten Stunde “kritisch” ist, bricht das reboot Script ab und überlässt es dem Admin den Reboot-Vorgang entsprechend vorzubereiten.

Das Script wurde unter Debian 5 Lenny sowie unter Ubuntu 10+11 eingesetzt.

safe-reboot.sh
#! /bin/bash
set -e
 
# Funktion des Scriptes:
########################
# reboote system, überprüfe jedoch VORHER ob beim reboot evtl ein
# filesystem check erforderlich wird (max mount count / age)
#
#
#######################################################################
# VERSION / CHANGES:
##################################################################
# 2010-02-17    A.Werner	RELEASE: Version 1.0
#
# 2010-04-21    A.Werner	FIX: examining ext2 parameters failed sometimes
#					if testing on ext2/ext3/ext4 volumes
#					where checking interval was disabled.
#				FIX: faulty date compare function rewritten
#					using  " date --date 'datestring' +%s "
#					solution.
#
#
#
#
#
##################################################################
#######################################################################
 
FLAG_FSCHECK_REQ=0
 
DISKVOLUMES=`mktemp`
DUMPINFO=`mktemp`
 
 
function cleanup {
	# Aufräumen
	rm $DISKVOLUMES
	rm $DUMPINFO
}
 
 
 
function checkrequired {
	############################
	# Function Descripion:
	########################
	# Function compares parameters MOUNT_COUNT + MAX_MOUNT_COUNT and
	# NEXT_CHECK + current date and RETURNS FALSE (1) if a filesystem check
	# is required on next boot. Else it RETURNS TRUE (0)
	#
	#
	#
 
	MOUNT_COUNT="$1"
	MOUNT_COUNT_PLUS="$(($MOUNT_COUNT+1))"
	MAX_MOUNT_COUNT="$2"
	NEXT_CHECK="$3" 
 
 
	CURRENT_DATE=`date +%s`
	# add a safty puffer of 1h/3600s to current date
	CURRENT_DATE_PLUS="$(($CURRENT_DATE+3600))"
 
	# Reseting FLAG to LOW... all clear.
	FLAG=0
 
	##############################################################
	##############################################################
	##
	##
	##
	#	 Entscheidungsbaum:
	#	 ===================
 
	# Given Variables:
	# 
	# MOUNT_COUNT:		2
	# MOUNT_COUNT_PLUS:	2+1 (for safty reasons)
	# MAX_MOUNT_COUNT:	31
	# NEXT_CHECK_UNIX_TIME:	22222222	(Unix time epoch in seconds)
	# CURRENT_DATE:		111111111	(Unix time epoch in seconds)
	# CURRENT_DATE_PLUS:	111111111+3600	(Unix time epoch in seconds, for safty reasons)
 
	if [ "$NEXT_CHECK" = "" ] ; then
		echo '!!!                                                           !!!'
		echo '!!! Seems this filesystem does not have set a check interval. !!!'
		echo '!!!                                                           !!!'
		# nichts weiter tun da keine vergleichswerte vorliegen.
	else
		# Vergleichswerte liegen vor. Daher weitere Tests...
		#echo "DEBUG: NEXT CHECK DATE FOUND: '$NEXT_CHECK'"	
		NEXT_CHECK_UNIX_TIME=`date --date "$NEXT_CHECK" +%s`
		#echo "DEBUG: NEXT_CHECK_UNIX_TIME: '$NEXT_CHECK_UNIX_TIME'"
		#echo "DEBUG: CURRENT_DATE_PLUS: '$CURRENT_DATE_PLUS'"
 
		if [ "$CURRENT_DATE_PLUS" -ge "$NEXT_CHECK_UNIX_TIME" ]; then
			# Else >> RAISE FLAG!
			FLAG=1
		fi
	fi
 
 
	# Wenn MOUNT_COUNT kleiner MAX_MOUNT_COUNT dann SKIP Else >> RAISE FLAG!
	if [ "$MOUNT_COUNT_PLUS" -ge "$MAX_MOUNT_COUNT" ] ; then
		FLAG=1
	fi
 
	return $FLAG
	##
	##
	##
	##############################################################
	##############################################################
}
 
 
 
##############################################################
#   MAIN
##########################################################
##
##
##
 
 
# finde/bestimme lokale Disk-Volumes
df -l | grep ^/dev/ | cut -d' ' -f1 | tr -d ' ' > "$DISKVOLUMES"
 
 
 
# frage jeweils FS Status ab
while read FILESYS
do
	dumpe2fs -h "$FILESYS" 2>/dev/null | grep -e 'Mount count:' \
					          -e 'Maximum mount count:' \
					          -e 'Last checked:' \
					          -e 'Next check after:' \
					          -e 'Check interval:' > "$DUMPINFO"
	echo "Examining Filesystem: $FILESYS"
	echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
	cat "$DUMPINFO"
	echo 
	echo
 
	# Extract Parameters for "checkrequired" function
	MOUNT_COUNT="`grep -e 'Mount count:' $DUMPINFO | cut -f2 -d':' | tr -d ' '`"
	#echo "DEBUG: MOUNT_COUNT='$MOUNT_COUNT'"
	MAX_MOUNT_COUNT="`grep -e 'Maximum mount count:' $DUMPINFO | cut -f2 -d':' | tr -d ' '`"
	#echo "DEBUG: MAX_MOUNT_COUNT='$MAX_MOUNT_COUNT'"
	NEXT_CHECK="`grep -e 'Next check after:' $DUMPINFO | cut -f'2-' -d':' | tr -s ' '`" 
	#echo "DEBUG: NEXT_CHECK='$NEXT_CHECK'"
 
 
	set +e
	# function parameters: [MOUNT_COUNT] [MAX_MOUNT_COUNT] [NEXT_CHECK]
	checkrequired "$MOUNT_COUNT" "$MAX_MOUNT_COUNT" "$NEXT_CHECK"
	RETURNCODE=$?
	set -e
 
	if [ $RETURNCODE = 1 ] ; then
		echo
		echo '!!!!!!!! This Volume requires a Filesystem-Check in next reboot !!!!!!!!'
		echo
		FLAG_FSCHECK_REQ=1
	else
		echo
		echo "Looks good. no FSCheck required."
		echo
	fi
done < "$DISKVOLUMES"
 
 
# wenn ein FS check evtl erforderlich wird melde dies und breche das script ab
if [ $FLAG_FSCHECK_REQ = 1 ] ; then
	echo
	echo
	echo "###############################################################"
	echo "!!! Seems there is a FS Check requirement on some Filesystem."
	echo "!!! Will NOT reboot. You will need to handle that manualy."
	echo "!!! Exiting now..."
	echo "###############################################################"
	echo
	echo
	cleanup
	exit
fi
 
# wenn kein fs check erforderlich ist, reboote das system.
cleanup
echo
echo
echo '!!! Rebooting in 10 seconds !!!'
echo '>>> PRESS CTRL+C TO CANCEL REBOOT PROCESS <<<'
sleep 10
reboot

Viel Erfolg damit!

Axel Werner 2011-09-04 09:43

it-artikel/safe-reboot.sh-script-zum-sicheren-rebooten-eines-servers-ohne-das-man-von-einem-ungeplanten-fsck-ueberrascht-wird.txt · Last modified: 2011-09-09 22:41 by mail@awerner.myhome-server.de