Es gibt hier schon ein Thema zum Watchdog, aber eher mit selbst entwickelter Hardware oder über Nutzung von Schaltaktoren. Ich habe für mich eine Lösung gefunden um den internen vorhandenen Hardware-Watchdog für die HomeMatic-Software (CCU2) zu nutzen.
Grundlage:
Die CCU2 ist eigentlich "nur" ein Mini-PC mit ARM-Prozessor auf dem Linux und die HomeMatic-Software läuft.
Der ARM-Prozessor hat bereits einen aktivierten Watchdog und ein kleines Programm unter Linux bedient diesen. Das Funktioniert so: Im Prozessor läuft eine kleine Uhr und zählt immer eine Sekunde aufwärts. Erreicht sie 60 Sekunden (vermutlich Standardeinstellung), dann startet der PC neu. Das soll aber i.d.R. natürlich nicht passieren und deswegen läuft zusätzlich/parallel ein kleines Software-Programm im Hintergrund (der watchdog-daemon), der alle 30 Sekunden (Standardeinstellung) den Hardware-Watchdog-Timer auf Null setzt. Im normalen Betrieb rennt die Uhr also immer nur bis max. 30 und dann wird zurückgesetzt. Die 60 Sekunden für die Reboot-Aktivierung wird also normalerweise nicht erreicht.
So, hängt sich der Computer aber auf, hängt auch der Watchdog-Daemon und es kann nicht mehr zurückgesetzt werden. Nach spätestens 60 Sekunden startet der Computer neu.
Das ist alles schon vorhanden und aktiv. Unser Problem ist aber, dass sich ggf. nur die HomeMatic-Software aufhängt, aber deswegen noch nicht der ganze PC. D.h. der Watchdog-Daemon kann in diesem Fall ganz ungestört weiterarbeiten und es kommt natürlich zu keinem Neustart.
Also, wir wollen keinen Wachhund der nur aufpasst ob alles zusammen abkratzt, sondern speziell wenn die HomeMatic-Software abkratzt. Das geht relativ einfach. Der Hardware-Watchdog-Zähler bleibt unberührt, aber statt dass er von einem kleinen Linux-Programm alle 30 Sekunden zurückgesetzt wird, soll die HomeMatic-Software diese Aufgabe übernehmen. D.h. kratzt nun die HomeMatic-Software ab, wird der Watchdog-Timer nicht mehr zurückgesetzt und die CCU startet neu. Kratzt der gesamte PC ab, wird auch neugestartet, weil in diesem Fall ja auch die HomeMatic-Software nicht mehr läuft.
Wie geht das?
Ganz einfach über 2 Scripte, eines auf dem Dateisystem der CCU2 und eines im WebUI.
Exkurs für Linux-Insider:
Im Grunde muss man nur den Linux-Daemon ausschalte, bzw. ihn beim Hochfahren nicht mehr automatisch starten. Das passiert in der Datei "/etc/init.d/S15watchdog". Leider auf einem Read-Only-Dateisystem, daher Sackgasse. Der Prozess "watchdog" muss 1x nach dem Booten mit dem kill-Befehl gestoppt werden. Und dann muss die HomeMatic-Software alle 1..59 Sekunden (Standard sind 30) den Watchdog-Timer zurücksetzen. Das passiert indem man irgend etwas in die Datei (Block-Device) /dev/watchdog schreibt.
Das Shell-Script prüft also ob der "normale" Watchdog-Daemon vorhanden ist (ob Prozess läuft) und wenn ja, wird er gekillt. Danach wird der Timer zurückgesetzt (mit "echo 1 > /dev/watchdog"). Um nicht alle 30 Sekunden nach dem Daemon suchen zu müssen, wird nach dem ersten Mal eine kleine Markierungsdatei in das flüchtige (tmpfs) Verzeichnis /tmp geschrieben (beim nächsten Neustart ist diese Datei weg und auch der Daemon wieder automatisch da).
Das Script selbs würde normalerweise unter /opt liegen, aber da dies auch Teil des ro Dateisystems ist, kommt nur /usr/local in Frage, der einzige rw Bereich.
Einrichten
1. Folgendes Shell-Script wird als Textdatei im Dateisystem der CCU2 gespeichert unter "/usr/local/bin/hm-watchdog.sh" (Ordner "bin" anlegen). Ihr könnt es über SSH (Benutzer = root, Standardpasswort = MuZhlo9n%8!G), FTP oder wie auch immer machen, aber nicht vergessen die Datei ausführbar zu machen (chmod 0755 ...)!
Code: Alles auswählen
#!/bin/sh
WATCHDOG_DEV=/dev/watchdog
TMP_MARK=/tmp/hm-watchdog
if [ ! -e "$TMP_MARK" ]; then
WATCHDOG_PID=$(ps -o pid,comm | grep watchdog | head -n 1 | tr -cd '[0-9]')
if [ -n "$WATCHDOG_PID" ] && kill -9 "$WATCHDOG_PID"; then
sync
echo "watchdog [$WATCHDOG_PID] killed."
echo 1 > "$WATCHDOG_DEV"
echo "$$WATCHDOG_PID" > "$TMP_MARK"
fi
fi
echo 1 > "$WATCHDOG_DEV"
sync
exit 0
Code: Alles auswählen
string stdout;
string stderr;
system.Exec("/usr/local/bin/hm-watchdog.sh", &stdout, &stderr);