Aus Ramershoven wurde berichtet, dass die Router mehrmals die Woche neu gestartet werden müssen. Auch ich habe schon beobachtet, dass Router nach längerem Betrieb Zeit in einen seltsamen Zustand geraten. Allerdings kann nicht mehrmals in der Woche. Warum dies so ist, ist nicht so einfach zu ermitteln. Es kommt nicht so häufig vor und lässt sich nicht gezielt reproduzieren. Eine vorübergehende Abhilfe soll ein prophylaktischer Neustart pro Tag mittels cron leisten.
Dazu habe ich heute ein wenig mit einem Cron-Job experimentiert. Eigentlich ist es ganz einfach, aber unter OpenWrt gibt es ein paar Haken. Es kann zu einem unendlichen Reboot kommen, wenn cron kurz nach dem Reboot ausgeführt wird. Dies liegt daran, dass die Uhrzeit beim Start des Routers anhand des letzten Zeitstempel der Dateien in /etc gesetzt wird. Wenn die Router-Zeit auf die Uhrzeit des Reboot gesetzt wird, wird sofort ein weiterer Reboot ausgeführt, der wiederum zum Reboot führt.
Um diesen unendlichen Reboot zu vermeiden, habe ich einen Ausdruck entwickelt, der 70 Sekunden wartet, dann den Zeitstempel von /etc/banner ändert und mittels uptime prüft, ob der Router mindestens eine Stunde gelaufen ist. Die Wartezeit von 70 Sekunden stellt auch sicher, dass der Router mindestens eine Minute gelaufen ist, bevor uptime aufgerufen wird.
Das Ausgabeformat von uptime ist nicht sonderlich freundlich für Abfragen, wie die Beispielausgabe von uptime zeigt.
15:29:31 up 5 days, 40 min, load average: 0.45, 0.50, 0.47 15:29:31 up 12:34, load average: 0.45, 0.50, 0.47 15:29:31 up 1 day, 55 min, load average: 0.45, 0.50, 0.47 15:29:31 up 3 days, 11:24, load average: 0.45, 0.50, 0.47
Innerhalb der ersten Stunde wird die Zeit, die der Router läuft in Minuten im Format ’n min,‘ angegeben. Nach einer Stunde wechselt das Ausgabeformat zu hh:mm, um nach jeweils 24 Stunden in das Format ’n days?, m min,‘ oder ‚ n days, hh:mm,‘ zu wechseln.
Indem die Ausgabe von uptime auf den String ‚ min,‘ geprüft wird, kann bestimmt werden, ob der Router bereits länger als eine Stunde läuft. Nur dann soll ein Reboot ausgeführt werden und ein unendlicher Reboot verhindert.
Das Vorgehen ist wie folgt:
- Es wird 70 Sekunden gewartet. Damit ist die Zeit garantiert eine Minute weiter.
- Das Datum der Datei /etc/banner wird auf die aktuelle Zeit gesetzt, damit der Rechner nicht mit der Reboot-Zeit startet.
- uptime wird aufgerufen und
- mittels grep darauf geprüft, ob der Router länger als eine Stunde an ist.
- Wenn nur ‚min‘ in der Ausgabe von uptime enthalten ist, dann entfällt der Neustart.
In der Datei /etc/crontabs/root ist dazu folgender Eintrag zu hinterlegen, der den Router jeden Tag um 5:05 Uhr neu startet.
5 5 * * * ((sleep 70 ; /bin/touch /etc/banner; uptime) | ( grep -e '\(day\|min\)' | grep -v 'day' )) || /sbin/reboot >/dev/null
Nach dem Eintrag z.B. mit crontab -e erfolgt ist, muss dem cron Dämon die Änderung mit /etc/init.d/cron reload bekannt gegeben werden.
Anmerkung: Wichtig ist eine Leerzeile am Ende der Datei, damit cron richtig funktioniert.
Genug für heute.
PS: Der Test, ob der Router länger als eine Stunde läuft, geht leichter über die Datei /proc/uptime. Der Befehl sieht dann so aus:
5 5 * * * sleep 70 ; /bin/touch /etc/banner; test `sed 's#\..*##' /proc/uptime` -ge 3600 && /sbin/reboot >/dev/null