summaryrefslogtreecommitdiff
path: root/cleopatre/application/fw_wd/fwwatchd
blob: add3a5c2a1dde5008820ac4643f623127bacba21 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#!/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 && { echo "watchdog" > /proc/reset_cause; reboot; } } || \
		exit 1
done