#!/bin/sh # Authorize automatic system reboot on watchdog expiration. REBOOT=true # Do not get trace from firmware and keep them compressed. TRACE_ENABLED=false # Trace folder. TRACE_FOLDER=/usr/local/trace/ # Trace basename. TRACE_BASENAME=trace_ # Header of the last trace, uncompressed. TRACE_HEADER_PATH=${TRACE_FOLDER}/last_head_trace.txt # Trace currently dumped, will be moved once finished. TRACE_DUMPING_PATH=${TRACE_FOLDER}/last_trace_dumping.gz # Number of lines to store in the uncompressed trace. TRACE_HEADER_LINE=3 # Load personnalize preferences. test -f /etc/default/fwwatchd && . /etc/default/fwwatchd # Do not continue if nothing to do. test $TRACE_ENABLED = true || exit 1 # Dump all information to be stored in trace. dump_trace () { tail -n +2 ${TRACE_FOLDER}/last_head_trace.txt cat /dev/trace IFSOLD=$IFS IFS=":" && for i in $TRACE_FILES; do IFS=$IFSOLD test -f "$i" && echo "==== $i ====" && cat "$i" && echo "" done IFS=":" && for i in $TRACE_CMDS; do IFS=$IFSOLD echo "==== $i ====" && $i && echo "" done IFS=$IFSOLD } # Get all trace information and store it on file system. get_trace () { test $TRACE_ENABLED = true || return 0 # Ensure trace folder is created. mkdir -p $TRACE_FOLDER || return 1 # Get list of traces, sort them (by the last number) # and handle case where there are no traces. last_trace=$(ls -1 $TRACE_FOLDER/$TRACE_BASENAME[0-9]*.gz 2>/dev/null \ | sort -n -k 2 -t _ | tail -n 1) # No trace file found. if [[ -z $last_trace ]]; then # Start at 1. new_trace_digit=1 else # Remove prefix & suffix. new_trace_digit=${last_trace##$TRACE_FOLDER/$TRACE_BASENAME} new_trace_digit=${new_trace_digit%%.gz} # Get trace + 1. new_trace_digit=$(expr $new_trace_digit + 1) fi # Get trace (uncompressed, then compressed), get files and execute # commands. new_trace=${TRACE_FOLDER}/${TRACE_BASENAME}${new_trace_digit}.gz echo "Full trace available in $new_trace" > ${TRACE_HEADER_PATH} && \ head -n ${TRACE_HEADER_LINE} /dev/trace >> ${TRACE_HEADER_PATH} && \ dump_trace | gzip -c > $TRACE_DUMPING_PATH mv $TRACE_DUMPING_PATH $new_trace } # Sleep until watchdog expires, get trace and reboot if requested. trap : TERM while true; do fw_wd & fw_wd_pid=$! wait $fw_wd_pid || { kill $fw_wd_pid 2>/dev/null; exit 1; } get_trace { test $REBOOT = true && reboot; } || \ exit 1 done