watchcat: add nopingtime option + refactoring 13940/head
authorVasily Trotzky <trotzky.vas@gmail.com>
Thu, 19 Nov 2020 11:50:39 +0000 (14:50 +0300)
committerVasily Trotzky <trotzky.vas@gmail.com>
Thu, 19 Nov 2020 11:50:39 +0000 (14:50 +0300)
nopingtime UCI option rationale:
I want relatively fast reaction(i.e. 1m or 2m) for 'no internet' condition,
but i don't want my router to reboot every 1 minute if there is still no
internet after reboot.

initd_watchcat:
* add: nopingtime uci option support
* add: defaults to all non-critical options
* add: log warnings for non-critical errors(when option is missed and
default is applyed)
* fix: error handling and config_get defaults are somtimes in conflict
because of config_get defaults. They are gone now, error handling improved.
* fix: calling watchcat.sh with 'period' mode instead of 'ping'. Typo?
* fix: pingperiod default changed from period/20 to more reasonable period/5

watchcat.sh:
* add: nopingtime uci option support( sleep if uptime < nopingtime )
* remove: [ "$mode" = "allways" ] && mode="always" - not needed, already
done by initd_watchcat in load_watchcat() func
* add: echo 1 > /proc/sys/kernel/sysrq before sysrq-trigger
* refactor: eliminated once used not needed variables, code size reduced.

* PKG_RELEASE bumped up

Signed-off-by: Vasily Trotzky <trotzky.vas@gmail.com>
utils/watchcat/Makefile
utils/watchcat/files/initd_watchcat
utils/watchcat/files/watchcat.sh

index 8153e617870ca1133738af0f46f5f3587d60c326..ec6e0895e50ff26414107361c6916d39c88ac001 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=watchcat
 PKG_VERSION:=1
-PKG_RELEASE:=7
+PKG_RELEASE:=8
 
 PKG_MAINTAINER:=Roger D <rogerdammit@gmail.com>
 PKG_LICENSE:=GPL-2.0
index 213186063410a92ba2062be6377cc28d9e4f3d12..b34b50edae8a8291da98018b383aca6887d7d972 100644 (file)
@@ -25,43 +25,80 @@ timetoseconds() {
 
 load_watchcat() {
        config_get period       $1 period
-       config_get mode         $1 mode         "always"
-       config_get pinghosts    $1 pinghosts    "8.8.8.8"
+       config_get mode         $1 mode
+       config_get pinghosts    $1 pinghosts
        config_get pingperiod   $1 pingperiod
-       config_get forcedelay   $1 forcedelay   "0"
-
+       config_get nopingtime   $1 nopingtime
+       config_get forcedelay   $1 forcedelay
+       
+       local nopingtime_dflt="900"
+       local forcedelay_dflt="60"
+       
        # Fix potential typo in mode (backward compatibility).
        [ "$mode" = "allways" ] && mode="always"
 
        error=""
-
-       timetoseconds "$period"
-       period="$seconds"
-       [ "$period" -ge 1 ] \
-               || append_string "error" 'period is not a valid time value (ex: "30"; "4m"; "6h"; "2d")' "; "
+       warn=""
+       
+       if [ -z "$period" ] 
+       then
+               append_string "error" "period is not set! Use time value(ex: '30'; '4m'; '6h'; '2d')." "; "     
+       else
+               timetoseconds "$period";period="$seconds"       
+               [ "$period" -ge 1 ] \
+                       || append_string "error" "period has invalid format! Use time value(ex: '30'; '4m'; '6h'; '2d')" "; "   
+       fi
+       
        [ "$mode" = "always" -o "$mode" = "ping" ] \
-               || append_string "error" "mode must be 'always' or 'ping'" "; "
-       [ -n "$pinghosts" -o "$mode" = "always" ] \
-               || append_string "error" "pinghosts must be set when in 'ping' mode" "; "
-       [ "$mode" = "ping" ] && {
-               if [ -n "$pingperiod" ]
+               || append_string "error" "mode must be 'always' or 'ping'" "; " 
+       
+       if [ -z "$forcedelay" ]
+       then
+               forcedelay="$forcedelay_dflt"           
+               append_string "warn" "forcedelay is not configured! Defaulted to $forcedelay seconds" "; "              
+       else
+               [ "$forcedelay" -ge 0 ] || {
+                       forcedelay="$forcedelay_dflt"           
+                       append_string "warn" "forcedelay is invalid! Defaulted to $forcedelay seconds" "; "             
+               }
+       fi
+       
+       [ -z "$error" -a "$mode" = "ping" ] && {                        
+               [ -z "$pinghosts" ] \
+                       && append_string "error" "pinghosts must be set in 'ping' mode! Use space separated address list (ex: '8.8.8.8 9.9.9.9')" "; "
+       
+               if [ -z "$nopingtime" ]
+               then
+                       nopingtime="$nopingtime_dflt"
+                       append_string "warn" "nopingtime is not configured! Defaulted to $nopingtime seconds" "; "                      
+               else
+                       timetoseconds "$nopingtime";nopingtime="$seconds"
+                       [ "$nopingtime" -ge 0 ] || {
+                               nopingtime="$nopingtime_dflt"
+                               append_string "warn" "nopingtime invalid format! Use time value(ex: '30'; '4m'; '6h'; '2d'). Defaulted to $nopingtime seconds" "; "
+                       }
+               fi
+               
+               local pingperiod_dflt="$((period/5))"
+                               
+               if [ -z "$pingperiod" ] 
                then
-                       timetoseconds "$pingperiod"
-                       pingperiod="$seconds"
-                       if [ "$pingperiod" -ge 0 ]
-                       then
-                               [ "$pingperiod" -lt "$period" ] \
-                                       || append_string "error" "pingperiod must be less than period" "; "
-                       else
-                               append_string "error" 'pingperiod is not a valid time value (ex: "30"; "4m"; "6h"; "2d")' "; "
-                       fi
+                       pingperiod="$pingperiod_dflt"
+                       append_string "warn" "pingperiod is not configured! Defaulted to $pingperiod seconds(1/5 of period)" "; "
                else
-                       pingperiod="$((period/20))"
+                       timetoseconds "$pingperiod";pingperiod="$seconds"
+                       [ "$pingperiod" -ge 0 -a "$pingperiod" -ge "$period" ] && {
+                               pingperiod="$pingperiod_dflt"
+                               append_string "warn" "pingperiod is invalid value(greater than period)! Defaulted to $pingperiod seconds(1/5 of period)" "; "
+                       }
+                       [ "$pingperiod" -ge 0 ] || {
+                               pingperiod="$pingperiod_dflt"                           
+                               append_string "warn" "pingperiod has invalid format! Use time value(ex: '30'; '4m'; '6h'; '2d'). Defaulted to $pingperiod seconds(1/5 of period)" "; "
+                       }                       
                fi
        }
-       [ "$forcedelay" -ge 0 ] \
-               || append_string "error" "forcedelay must be a integer greater or equal than 0, where 0 means disabled" "; "
-
+       
+       [ -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; }
 
        if [ "$mode" = "always" ]
@@ -69,8 +106,8 @@ load_watchcat() {
                /usr/bin/watchcat.sh "always" "$period" "$forcedelay" &
                logger -p user.info -t "watchcat" "started task (mode=$mode;period=$period;forcedelay=$forcedelay)"
        else
-               /usr/bin/watchcat.sh "period" "$period" "$forcedelay" "$pinghosts" "$pingperiod" &
-               logger -p user.info -t "watchcat" "started task (mode=$mode;period=$period;pinghosts=$pinghosts;pingperiod=$pingperiod;forcedelay=$forcedelay)"
+               /usr/bin/watchcat.sh "ping" "$period" "$forcedelay" "$pinghosts" "$pingperiod" "$nopingtime" &
+               logger -p user.info -t "watchcat" "started task (mode=$mode;period=$period;pinghosts=$pinghosts;pingperiod=$pingperiod;forcedelay=$forcedelay;nopingtime=$nopingtime)"
        fi
 
        echo $! >> "${PIDFILE}.pids"
index 5b157de3d1f2f2c846836d02b044cd54efe6c017..ca660bb13923a8f00b893dff931895e7c102ff46 100644 (file)
@@ -5,19 +5,12 @@
 # This is free software, licensed under the GNU General Public License v2.
 #
 
-mode="$1"
-
-# Fix potential typo in mode (backward compatibility).
-[ "$mode" = "allways" ] && mode="always"
-
-shutdown_now() {
-       local forcedelay="$1"
-
+reboot_now() {
        reboot &
 
-       [ "$forcedelay" -ge 1 ] && {
-               sleep "$forcedelay"
-
+       [ "$1" -ge 1 ] && {
+               sleep "$1"
+               echo 1 > /proc/sys/kernel/sysrq
                echo b > /proc/sysrq-trigger # Will immediately reboot the system without syncing or unmounting your disks.
        }
 }
@@ -25,31 +18,29 @@ shutdown_now() {
 watchcat_always() {
        local period="$1"; local forcedelay="$2"
 
-       sleep "$period" && shutdown_now "$forcedelay"
+       sleep "$period" && reboot_now "$forcedelay"
 }
 
 watchcat_ping() {
-       local period="$1"; local forcedelay="$2"; local pinghosts="$3"; local pingperiod="$4"
+       local period="$1"; local forcedelay="$2"; local pinghosts="$3"; local pingperiod="$4"; local nopingtime="$5"
 
-       time_now="$(cat /proc/uptime)"
-       time_now="${time_now%%.*}"
-       time_lastcheck="$time_now"
-       time_lastcheck_withinternet="$time_now"
+       local time_now="$(cat /proc/uptime)";time_now="${time_now%%.*}"
+
+       [ "$time_now" -lt "$nopingtime" ] && sleep "$((nopingtime-time_now))"
+
+       time_now="$(cat /proc/uptime)";time_now="${time_now%%.*}"
+       local time_lastcheck="$time_now"
+       local time_lastcheck_withinternet="$time_now"
 
        while true
        do
                # account for the time ping took to return. With a ping time of 5s, ping might take more than that, so it is important to avoid even more delay.
-               time_now="$(cat /proc/uptime)"
-               time_now="${time_now%%.*}"
-               time_diff="$((time_now-time_lastcheck))"
+               time_now="$(cat /proc/uptime)"; time_now="${time_now%%.*}"
+               local time_diff="$((time_now-time_lastcheck))"
 
-               [ "$time_diff" -lt "$pingperiod" ] && {
-                       sleep_time="$((pingperiod-time_diff))"
-                       sleep "$sleep_time"
-               }
+               [ "$time_diff" -lt "$pingperiod" ] && sleep "$((pingperiod-time_diff))"
 
-               time_now="$(cat /proc/uptime)"
-               time_now="${time_now%%.*}"
+               time_now="$(cat /proc/uptime)";time_now="${time_now%%.*}"
                time_lastcheck="$time_now"
 
                for host in $pinghosts
@@ -57,21 +48,18 @@ watchcat_ping() {
                        if ping -c 1 "$host" &> /dev/null
                        then
                                time_lastcheck_withinternet="$time_now"
-                       else
-                               time_diff="$((time_now-time_lastcheck_withinternet))"
-                               logger -p daemon.info -t "watchcat[$$]" "no internet connectivity for $time_diff seconds. Reseting when reaching $period"
+                       else                                                            
+                               logger -p daemon.info -t "watchcat[$$]" "no internet connectivity for $((time_now-time_lastcheck_withinternet)). Reseting when reaching $period"
                        fi
                done
-
-               time_diff="$((time_now-time_lastcheck_withinternet))"
-               [ "$time_diff" -ge "$period" ] && shutdown_now "$forcedelay"
-
+               
+               [ "$((time_now-time_lastcheck_withinternet))" -ge "$period" ] && reboot_now "$forcedelay"
        done
 }
 
-       if [ "$mode" = "always" ]
-       then
-               watchcat_always "$2" "$3"
-       else
-               watchcat_ping "$2" "$3" "$4" "$5"
-       fi
+if [ "$1" = "always" ]
+then
+       watchcat_always "$2" "$3"
+else
+       watchcat_ping "$2" "$3" "$4" "$5" "$6"
+fi