From cfa65355cff0290cd276f3bb292fdadf954fe87d Mon Sep 17 00:00:00 2001 From: Nuno Goncalves Date: Sat, 18 Dec 2010 23:56:42 +0000 Subject: [PATCH] [packages] add package watchcat: Allows to configure a periodically reboot, or after loosing internet connectivity SVN-Revision: 24692 --- utils/watchcat/Makefile | 39 ++++++ utils/watchcat/files/initd_watchcat | 139 +++++++++++++++++++++ utils/watchcat/files/uci_defaults_watchcat | 7 ++ 3 files changed, 185 insertions(+) create mode 100644 utils/watchcat/Makefile create mode 100644 utils/watchcat/files/initd_watchcat create mode 100644 utils/watchcat/files/uci_defaults_watchcat diff --git a/utils/watchcat/Makefile b/utils/watchcat/Makefile new file mode 100644 index 0000000000..1c68251fe9 --- /dev/null +++ b/utils/watchcat/Makefile @@ -0,0 +1,39 @@ +# +# Copyright (C) 2010 segal.di.ubi.pt +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=watchcat +PKG_VERSION:=1 +PKG_RELEASE:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/watchcat + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Enable the configuration of programed reboots + MAINTAINER:=Nuno Goncalves +endef + +define Package/watchcat/description +Allows to configure a periodically reboot, or after loosing internet connectivity. Configured trough UCI /etc/config/system +endef + +define Package/watchcat/conffiles +/etc/config/system +endef + +define Build/Compile +endef + +define Package/watchcat/install + $(CP) ./files/initd_watchcat $(1)/etc/init.d/watchcat + $(CP) ./files/uci_defaults_watchcat $(1)/etc/defaults/50-watchcat +endef + +$(eval $(call BuildPackage,watchcat)) diff --git a/utils/watchcat/files/initd_watchcat b/utils/watchcat/files/initd_watchcat new file mode 100644 index 0000000000..4d2f6d4ffc --- /dev/null +++ b/utils/watchcat/files/initd_watchcat @@ -0,0 +1,139 @@ +#!/bin/sh /etc/rc.common + +START=01 + +PIDFILE="/tmp/run/watchcat" + +append_string() { + local varname="$1"; local actual="${!varname}"; local add="$2"; local separator="${3:- }" + new="${actual:+$actual$separator}$add" + eval "$varname=\$new" +} + +shutdown_now() { + local forcedelay="$1" + + reboot & + + [ "$forcedelay" -ge 1 ] && { + sleep $forcedelay + + echo b > /proc/sysrq-trigger # Will immediately reboot the system without syncing or unmounting your disks. + } +} + +watchcat_allways() { + local period="$1"; local forcedelay="$2" + + sleep $period && shutdown_now "$forcedelay" +} + +watchcat_ping() { + local period="$1"; local forcedelay="$2"; local pinghosts="$3"; local pingperiod="$4" + + time=$(cat /proc/uptime) && time=${time%%.*} + last=$time + + while true + do + sleep $pingperiod + + time=$(cat /proc/uptime) && time=${time%%.*} + + for host in "$pinghosts" + do + if ping -c 1 "$host" &> /dev/null + then + last=$time + else + diff=$((time-last)) + logger -p daemon.info -t "watchcat[$$]" "no internet connectivity for $diff seconds. Reseting when reaching $period" + fi + done + + diff=$((time-last)) + [ $diff -ge $period ] && shutdown_now "$forcedelay" + + done +} + +timetoseconds() { + local time=$1 + unset seconds + + { [ "$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)); } +} + +load_watchcat() { + config_get period $1 period + config_get mode $1 mode "allways" + config_get pinghosts $1 pinghosts "8.8.8.8" + config_get pingperiod $1 pingperiod "600" + config_get forcedelay $1 forcedelay "0" + + error="" + + timetoseconds "$period" + period="$seconds" + [ "$period" -ge 1 ] \ + || append_string "error" "period is not set or not recognized" "; " + [ "$mode" = "allways" -o "$mode" = "ping" ] \ + || append_string "error" "mode must be 'allways' or 'ping'" "; " + [ -n "$pinghosts" -o "$mode" = "allways" ] \ + || append_string "error" "pinghosts must be set in 'ping' mode" "; " + timetoseconds "$pingperiod" + pingperiod="$seconds" + [ "$pingperiod" -l "$period" -o "$mode" = "allways" ] \ + || append_string "error" "pingperiod is not recognized" "; " + [ "$forcedelay" -ge 0 ] \ + || append_string "error" "forcedelay must be a integer greater or equal than 0, where 0 means disabled" "; " + + [ -n "$error" ] && { logger -p user.err -t "watchcat" "reboot program $1 not started - $error"; return; } + + if [ "$mode" = "allways" ] + then + watchcat_allways "$period" "$forcedelay" & + else + watchcat_ping "$period" "$forcedelay" "$pinghosts" "$pingperiod" & + fi + + echo $! >> "$PIDFILE".pids + + logger -p user.info -t "sshtunnel" "started tunnels to $server (pid=$!;retrydelay=$retrydelay)" +} + +stop() { + if [ -f "$PIDFILE".pids ] + then + logger -p user.info -t "watchcat" "stopping all reboot programs" + + while read pid + do + kill $pid + done < "$PIDFILE".pids + + rm "$PIDFILE".pids + + logger -p user.info -t "watchcat" "all reboot programs stopped" + else + logger -p user.info -t "watchcat" "no reboot programs running" + fi +} + +start() { + [ -f "$PIDFILE".pids ] && stop + + config_load system + if [ -n "$(uci show system.@watchcat[0])" ] # at least one watchcat section exists + then + logger -p user.info -t "watchcat" "starting all reboot programs" + config_foreach load_watchcat watchcat + logger -p user.info -t "watchcat" "all reboot programs started" + else + logger -p user.info -t "watchcat" "no reboot programs defined" + fi +} diff --git a/utils/watchcat/files/uci_defaults_watchcat b/utils/watchcat/files/uci_defaults_watchcat new file mode 100644 index 0000000000..5b01e699b5 --- /dev/null +++ b/utils/watchcat/files/uci_defaults_watchcat @@ -0,0 +1,7 @@ +#!/bin/sh +uci add system watchcat +uci set system.@watchcat[0].period=6h +uci set system.@watchcat[0].mode=ping +uci set system.@watchcat[0].pinghosts=8.8.8.8 +uci set system.@watchcat[0].forcedelay=30 +uci commit -- 2.30.2