270 lines
8.0 KiB
Bash
270 lines
8.0 KiB
Bash
#!/bin/sh
|
|
# checks boot options to see what to do when the system has a flash configuration corruption
|
|
STAG=checkflashcfg:
|
|
PENDINGCHK=/tmp/.boot_pending
|
|
# lock wait time max 15mn * 60 = 900 secs (sufficient time to check it)
|
|
LOCKWAIT=900
|
|
bname=checkflashcfg
|
|
_curr_dir=""
|
|
__USESYSLOG=1
|
|
VERBOSE=''
|
|
__EXITCODE=0
|
|
CONFIGMOUNT=/mnt/rom/user
|
|
CONFIGMOUNTTYPE=jffs2
|
|
DEVCONFIG=/dev/mtdblock9
|
|
tempdir=""
|
|
TMPMOUNT=/tmp/.mnt_config
|
|
__NOHANG=0
|
|
_RECOVERY=1
|
|
|
|
readonly LOCKFILE_DIR=/var/lock
|
|
readonly LOCK_FD=977
|
|
|
|
# Get boot options configuration file
|
|
if [ -f "/etc/bootoptions.conf" ]; then
|
|
source "/etc/bootoptions.conf"
|
|
fi
|
|
|
|
lock() {
|
|
local prefix=$1
|
|
local fd=${2:-$LOCK_FD}
|
|
local lock_file=$LOCKFILE_DIR/$prefix.lock
|
|
|
|
# still allow to run unlocked if the lock dir does not exist
|
|
if [ ! -d "${LOCKFILE_DIR}" ]; then
|
|
return 0
|
|
fi
|
|
|
|
# create lock file
|
|
eval "exec $fd>$lock_file"
|
|
# still allow to run unlocked if the lock file cannot be created
|
|
if [ $? -ne 0 ]; then
|
|
return 0
|
|
fi
|
|
|
|
# acquier the lock
|
|
flock -w ${LOCKWAIT} $fd \
|
|
&& return 0 \
|
|
|| return 1
|
|
}
|
|
|
|
unlock() {
|
|
local prefix=$1
|
|
local fd=${2:-$LOCK_FD}
|
|
local lock_file=$LOCKFILE_DIR/$prefix.lock
|
|
|
|
# release the lock
|
|
flock -u $fd
|
|
sync
|
|
}
|
|
|
|
function my_exit()
|
|
{
|
|
trap - SIGINT
|
|
trap - SIGQUIT
|
|
trap - SIGTERM
|
|
trap - SIGHUP
|
|
sync
|
|
if [ -d "${tempdir}" ]; then
|
|
if mount | grep -q "${tempdir}"; then
|
|
umount "$tempdir"
|
|
fi
|
|
rmdir "$tempdir"
|
|
fi
|
|
cd "$_curr_dir"
|
|
unlock $bname
|
|
exit $*
|
|
}
|
|
|
|
checkrecovery() {
|
|
if mount | grep -q "on / type nfs" ; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
function __sig_int {
|
|
log_write " "
|
|
log_write "$STAG WARNING: SIGINT caught"
|
|
my_exit 110
|
|
}
|
|
|
|
function __sig_quit {
|
|
log_write " "
|
|
log_write "$STAG WARNING: SIGQUIT caught"
|
|
my_exit 111
|
|
}
|
|
|
|
function __sig_term {
|
|
log_write " "
|
|
log_write "$STAG WARNING: SIGTERM caught"
|
|
my_exit 112
|
|
}
|
|
|
|
function __sig_hup {
|
|
log_write " "
|
|
log_write "$STAG WARNING: SIGHUP caught"
|
|
my_exit 113
|
|
}
|
|
|
|
checkflashconfig() {
|
|
if ! grep -q "$* " /proc/mounts; then
|
|
return 14
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
function log_write()
|
|
{
|
|
if [ ! -z ${VERBOSE} ] || [ ${__USESYSLOG} -eq 0 ]; then
|
|
echo "$*"
|
|
fi
|
|
if [ ${__USESYSLOG} -ne 0 ] ; then
|
|
logger -p local4.info "$*"
|
|
fi
|
|
}
|
|
|
|
function show_help {
|
|
echo "checkflashcfg help information:"
|
|
echo "Usage: checkflashcfg [ [ [-d] [-n] ] | [--help] ]"
|
|
echo "Verify boot options and flash config state to learn what to do when corrupted"
|
|
echo "WARNING: this script may intentionnaly hang if -n is not provided and flash is corrupted"
|
|
echo " if not hanging, it may attempt to recreate an unmountable corrupted flash"
|
|
echo " config partition"
|
|
echo " -d # print debug verbose info"
|
|
echo " -n # no hang even if boot option specifies blocking in corruption"
|
|
echo " --help # displays this help information"
|
|
echo "example: checkflashcfg; # checks flash corruption and boot options silently"
|
|
echo "example: checkflashcfg -d -n;# checks flash corruption and boot options verbose, no hang"
|
|
}
|
|
|
|
if [ -e "${PENDINGCHK}" ]; then
|
|
echo "$STAG Pending reboot, could not run!"
|
|
exit 97
|
|
fi
|
|
|
|
_curr_dir=`pwd`
|
|
|
|
# Lock to test a single instance is running, and exit if wait timeout
|
|
echo "$STAG Checking if allowed to run..."
|
|
lock $bname || ( echo "$STAG Checking if allowed to run... failed"; exit 100 )
|
|
echo "$STAG Checking if allowed to run... done"
|
|
|
|
# Set TRAPs to release lock if forced to exit
|
|
trap __sig_int SIGINT
|
|
trap __sig_quit SIGQUIT
|
|
trap __sig_term SIGTERM
|
|
trap __sig_hup SIGHUP
|
|
|
|
if [ -e "${PENDINGCHK}" ]; then
|
|
echo "$STAG Pending reboot, could not run!"
|
|
my_exit 97
|
|
fi
|
|
|
|
#keeps log file from getting big
|
|
rm /var/log/$LOG_FILE >/dev/null 2>&1
|
|
|
|
TOTALARG=$#
|
|
while getopts :dn- FLAG; do
|
|
case $FLAG in
|
|
d ) VERBOSE=1;;
|
|
n ) __NOHANG=1;;
|
|
'-')
|
|
show_help
|
|
my_exit 0;;
|
|
\?)
|
|
log_write "Invalid option: -$OPTARG" && my_exit 1;;
|
|
\:)
|
|
log_write "Required argument not found for option: -$OPTARG" && my_exit 2;;
|
|
esac
|
|
done
|
|
|
|
# removes processed option(s) from the cmd line args
|
|
shift $((OPTIND-1))
|
|
|
|
log_write "$STAG checking..."
|
|
|
|
# checks if user flash is mounted correctly
|
|
if ! checkflashconfig "$CONFIGMOUNT" "$CONFIGMOUNTTYPE" ; then
|
|
# verifies if in recovery mode
|
|
checkrecovery
|
|
_RECOVERY=$?
|
|
# checks if the block boot option is active from bootoptions.conf
|
|
if [ ${BLOCKOPTION} -eq 1 ]; then
|
|
if [ ${__NOHANG} -ne 1 ]; then
|
|
if [ $_RECOVERY -eq 0 ]; then
|
|
log_write "$STAG script process is blocked as flash config is in recovery mode!"
|
|
else
|
|
log_write "$STAG script process is blocked as flash config needs to be repaired!"
|
|
fi
|
|
_MYCOUNTER=0
|
|
# makes sure the watchdog is manually started as systemd booting seq would be stuck to our process
|
|
/etc/init.d/watchdog.sh start
|
|
#loops forever to make sure any dependant service won't start when booting
|
|
while [ $_MYCOUNTER -eq 0 ]; do
|
|
sleep 1s
|
|
done
|
|
else
|
|
if [ $_RECOVERY -ne 0 ]; then
|
|
log_write "$STAG flash config needs to be repaired!"
|
|
__EXITCODE=3
|
|
fi
|
|
fi
|
|
else
|
|
if [ $_RECOVERY -ne 0 ]; then
|
|
# checks if flash could be mounted correctly
|
|
tempdir=`mktemp -d`
|
|
if [ $? -ne 0 ]; then
|
|
log_write "$STAG could not create tmp directory!"
|
|
my_exit 4
|
|
fi
|
|
if ! mount -t ${CONFIGMOUNTTYPE} -o ro,noatime,sync ${DEVCONFIG} ${tempdir}; then
|
|
# we need to recreate flash content cause the system could not self warns the problem
|
|
# and the flash is not mountable
|
|
log_write "$STAG recreating configuration flash partition..."
|
|
_C_RES=$(flash_erase -j /dev/mtd9 0 0 2>&1)
|
|
_C_RET=$?
|
|
if [ $_C_RET -ne 0 ]; then
|
|
log_write "Warning: cannot recreate flash partition!"
|
|
__EXITCODE=5
|
|
else
|
|
log_write "$STAG recreating configuration flash partition... Done"
|
|
# attempt to use mountuser tool to get flash access
|
|
_C_RES=$(/usr/bin/mountuser rw 2>&1)
|
|
_C_RET=$?
|
|
if [ $_C_RET -eq 0 ]; then
|
|
log_write "$STAG recreating config flash partition content..."
|
|
cp -rf $CONFIGMOUNT/* $TMPMOUNT
|
|
if [ $? -ne 0 ]; then
|
|
log_write "Warning: cannot copy current config to flash mount!"
|
|
__EXITCODE=6
|
|
else
|
|
echo "---------------------------" >> $TMPMOUNT/config/motd
|
|
echo "Attempted to recreate Flash" >> $TMPMOUNT/config/motd
|
|
echo "---------------------------" >> $TMPMOUNT/config/motd
|
|
_C_RES=$(/usr/bin/mountuser ro 2>&1)
|
|
_C_RET=$?
|
|
if [ $_C_RET -ne 0 ]; then
|
|
log_write "Warning: cannot remount flash mount to read only!"
|
|
__EXITCODE=7
|
|
else
|
|
log_write "$STAG recreating config flash partition content... Done"
|
|
fi
|
|
fi
|
|
else
|
|
log_write "$STAG cannot access flash for rw access!"
|
|
__EXITCODE=8
|
|
fi
|
|
fi
|
|
else
|
|
log_write "$STAG flash is mountable, won't be automatically repaired!"
|
|
__EXITCODE=9
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
log_write "$STAG checking... Done"
|
|
my_exit $__EXITCODE
|