blob: 85535199efed22a64f957c8897c8185db8de3a3f (
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
|
#!/bin/sh /etc/rc.common
# In recent (relevant) versions of shellcheck busybox is a valid shell type
# shellcheck shell=busybox
# shellcheck disable=SC2034
USE_PROCD=1
START=97
STOP=01
# shellcheck source=/dev/null
. /lib/functions/watchcat.sh
append_string() {
varname="$1"
add="$2"
separator="${3:- }"
local actual
eval "actual=\$$varname"
new="${actual:+$actual$separator}$add"
eval "$varname=\$new"
}
time_to_seconds() {
time=$1
{ [ "$time" -ge 1 ] 2>/dev/null && seconds="$time"; } ||
{ [ "${time%s}" -ge 1 ] 2>/dev/null && seconds="${time%s}"; } ||
{ [ "${time%m}" -ge 1 ] 2>/dev/null && seconds=$((${time%m} * 60)); } ||
{ [ "${time%h}" -ge 1 ] 2>/dev/null && seconds=$((${time%h} * 3600)); } ||
{ [ "${time%d}" -ge 1 ] 2>/dev/null && seconds=$((${time%d} * 86400)); }
# shellcheck disable=SC2086
echo $seconds
unset seconds
unset time
}
config_watchcat() {
# Read config
config_get period "$1" period "120"
config_get mode "$1" mode "ping_reboot"
config_get pinghosts "$1" pinghosts "8.8.8.8"
config_get pingperiod "$1" pingperiod "60"
config_get forcedelay "$1" forcedelay "60"
config_get pingsize "$1" pingsize "standard"
config_get interface "$1" interface
config_get mmifacename "$1" mmifacename "null"
config_get_bool unlockbands "$1" unlockbands "0"
config_get_bool reset_failure_timer "$1" reset_failure_timer "0"
config_get addressfamily "$1" addressfamily "any"
config_get script "$1" script
# Fix potential typo in mode and provide backward compatibility.
[ "$mode" = "allways" ] && mode="periodic_reboot"
[ "$mode" = "always" ] && mode="periodic_reboot"
[ "$mode" = "ping" ] && mode="ping_reboot"
# Checks for settings common to all operation modes
if [ "$mode" != "periodic_reboot" ] && [ "$mode" != "ping_reboot" ] && [ "$mode" != "restart_iface" ] && [ "$mode" != "run_script" ]; then
append_string "error" "mode must be 'periodic_reboot' or 'ping_reboot' or 'restart_iface' or 'run_script'" "; "
fi
period="$(time_to_seconds "$period")"
[ "$period" -ge 1 ] ||
append_string "error" "period has invalid format. Use time value(ex: '30'; '4m'; '6h'; '2d')" "; "
# ping_reboot mode and restart_iface mode specific checks
if [ "$mode" = "ping_reboot" ] || [ "$mode" = "restart_iface" ] || [ "$mode" = "run_script" ]; then
if [ -z "$error" ]; then
pingperiod_default="$((period / 5))"
pingperiod="$(time_to_seconds "$pingperiod")"
if [ "$pingperiod" -ge 0 ] && [ "$pingperiod" -ge "$period" ]; then
pingperiod="$(time_to_seconds "$pingperiod_default")"
append_string "warn" "pingperiod cannot be greater than $period. Defaulted to $pingperiod_default seconds (1/5 of period)" "; "
fi
if [ "$pingperiod" -lt 0 ]; then
append_string "warn" "pingperiod cannot be a negative value." "; "
fi
# shellcheck disable=SC2154
if [ "$mmifacename" != "null" ] && [ "$period" -lt 30 ]; then
append_string "error" "Check interval is less than 30s. For robust operation with ModemManager modem interfaces it is recommended to set the period to at least 30s."
fi
fi
fi
if [ "$mode" = "run_script" ] && [ -z "$script" ]; then
append_string "error" "run_script mode requires a script"
fi
# ping_reboot mode and periodic_reboot mode specific checks
if [ "$mode" = "ping_reboot" ] || [ "$mode" = "periodic_reboot" ]; then
forcedelay="$(time_to_seconds "$forcedelay")"
fi
[ -n "$warn" ] && logger -p user.warn -t "watchcat" "$1: $warn"
[ -n "$error" ] && {
logger -p user.err -t "watchcat" "reboot program $1 not started - $error"
return
}
# Need to conditionally run mode functions because they have different signatures
case "$mode" in
periodic_reboot)
procd_open_instance "watchcat_${1}"
procd_set_param command /usr/bin/watchcat.sh "periodic_reboot" "$period" "$forcedelay"
procd_set_param respawn "${respawn_threshold:-3600}" "${respawn_timeout:-5}" "${respawn_retry:-5}"
procd_close_instance
;;
ping_reboot)
procd_open_instance "watchcat_${1}"
# shellcheck disable=SC2154
procd_set_param command /usr/bin/watchcat.sh "ping_reboot" "$period" "$forcedelay" "$pinghosts" "$pingperiod" "$pingsize" "$addressfamily" "$interface"
procd_set_param respawn "${respawn_threshold:-3600}" "${respawn_timeout:-5}" "${respawn_retry:-5}"
procd_close_instance
;;
restart_iface)
procd_open_instance "watchcat_${1}"
# shellcheck disable=SC2154
procd_set_param command /usr/bin/watchcat.sh \
"restart_iface" "$period" "$pinghosts" "$pingperiod" \
"$pingsize" "$interface" "$mmifacename" "$unlockbands" \
"$addressfamily" "" "$reset_failure_timer"
procd_set_param respawn "${respawn_threshold:-3600}" "${respawn_timeout:-5}" "${respawn_retry:-5}"
procd_close_instance
;;
run_script)
procd_open_instance "watchcat_${1}"
procd_set_param command /usr/bin/watchcat.sh \
"run_script" "$period" "$pinghosts" "$pingperiod" \
"$pingsize" "$interface" "$addressfamily" "$script" \
"$reset_failure_timer"
procd_set_param respawn "${respawn_threshold:-3600}" "${respawn_timeout:-5}" "${respawn_retry:-5}"
procd_close_instance
;;
*)
echo "Error starting Watchcat service. Invalid mode selection: $mode"
;;
esac
}
start_service() {
# procd expects $1 to be a specific instance
if [ "$2" = "ifup-any" ]; then
logger -p daemon.notice -t "watchcat[$$]" "Restarting due to an interface up with any unresolved interface."
fi
config_load watchcat
config_foreach config_watchcat watchcat
}
# Setup trigger in procd for changes to specified network interface
add_interface_trigger() {
local section="$1"
local ret=1
local interface mode logical
config_get mode "$section" mode "ping_reboot"
config_get interface "$section" interface
# Fix potential typo in mode and provide backward compatibility.
[ "$mode" = "allways" ] && mode="periodic_reboot"
[ "$mode" = "always" ] && mode="periodic_reboot"
[ "$mode" = "ping" ] && mode="ping_reboot"
# ping_reboot mode and restart_iface mode specific checks
if [ "$mode" = "ping_reboot" ] || [ "$mode" = "restart_iface" ] || [ "$mode" = "run_script" ]; then
[ -n "$interface" ] || return
logical="$(watchcat_resolve_restart_iface "$interface")"
ret=$?
if [ -n "$logical" ] && [ "$ret" -eq 0 ]; then
procd_add_interface_trigger "interface.*.up" "$logical" "/etc/init.d/watchcat" "restart"
else
has_failed_interface_resolve="true"
fi
fi
}
service_triggers() {
local has_failed_interface_resolve="false"
procd_add_reload_trigger "watchcat"
config_load watchcat
config_foreach add_interface_trigger watchcat
if [ "$has_failed_interface_resolve" = "true" ]; then
# PROCD_RELOAD_DELAY is defined in /lib/functions/procd.sh, sourced by /etc/rc.common on the live device
# procd expects parameter after script action (here, restart) to be a specific instance
procd_add_raw_trigger "interface.*.up" "$PROCD_RELOAD_DELAY" "/etc/init.d/watchcat" "restart" "" "ifup-any"
fi
}
|