From cb0a4b035dceba6fb1a35d0d8132476024c43234 Mon Sep 17 00:00:00 2001 From: Michael Sauer Date: Sat, 12 Sep 2026 12:21:26 +0200 Subject: [PATCH] fix: Startaufruf absichern und Neustartschleife der Station deckeln - 'on' fing bisher nur einen bereits laufenden, aber toten Dienst ab. Scheiterte schon der Aufruf "systemctl start" selbst (z.B. start-limit-hit nach einer Absturzserie durch Restart=always), beendete set -eu das Skript dort, bevor die Lebendigkeitspruefung je erreicht wurde - der eben hochgefahrene Zugangspunkt blieb offen ohne Server dahinter stehen. Der Startaufruf wird jetzt selbst abgefangen und faehrt im Fehlerfall dieselbe Rueckabwicklung wie die is-active-Pruefung. "systemctl reset-failed" vor dem Start verhindert, dass eine fruehere Absturzserie den naechsten ehrlichen Versuch blockiert. - Stirbt der Dienst nach einem erfolgreichen Start, stoppt das Skript ihn jetzt explizit, bevor es den Zugangspunkt herunterfaehrt und "abgeschaltet" meldet - sonst haette ein mit Restart=always weiterlaufender Dienst im Hintergrund einen saubereren Zustand suggeriert, als tatsaechlich vorlag. - ninlight-station.service setzt StartLimitIntervalSec/StartLimitBurst jetzt explizit statt sich stillschweigend auf systemds Vorgabewerte zu verlassen, mit Begruendung als Kommentar: ohne Zugangspunkt kann server.py nicht binden und stirbt sofort, Restart=always soll das nach kurzer Zeit ehrlich aufgeben statt das Journal zu fluten. Co-Authored-By: Claude Sonnet 5 --- tools/station/ninlight-station | 17 ++++++++++++++++- tools/station/ninlight-station.service | 8 ++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/tools/station/ninlight-station b/tools/station/ninlight-station index dfce1fe..974ea64 100755 --- a/tools/station/ninlight-station +++ b/tools/station/ninlight-station @@ -38,7 +38,18 @@ on) n=$(images | wc -l | tr -d ' ') [ "$n" -gt 0 ] || echo "Warnung: $IMAGE_DIR enthaelt kein Image - die Station antwortet auf alles mit 404" >&2 sudo nmcli con up "$AP_CONNECTION" >/dev/null - sudo systemctl start ninlight-station + # Eine fruehere Absturzserie darf den naechsten ehrlichen Versuch nicht + # blockieren (systemd verweigert "start" sonst sofort mit "start-limit-hit"). + sudo systemctl reset-failed ninlight-station 2>/dev/null || true + if ! sudo systemctl start ninlight-station; then + # Der Start-Aufruf selbst ist gescheitert (z.B. start-limit-hit) - unter + # set -eu wuerde das Skript hier sonst abbrechen, bevor die + # Lebendigkeitspruefung unten je erreicht wird, und der eben + # hochgefahrene Zugangspunkt bliebe offen ohne Server dahinter stehen. + sudo nmcli con down "$AP_CONNECTION" >/dev/null 2>&1 || true + echo "Fehler: ninlight-station liess sich nicht starten - Zugangspunkt wieder abgeschaltet. Details: journalctl -u ninlight-station" >&2 + exit 1 + fi # "systemctl start" meldet bei Type=simple schon Erfolg, sobald der Prozess # gestartet wurde - nicht, sobald er ueberlebt hat. Kurz warten und wirklich # nachsehen, sonst bleibt ein offener AP ohne Server dahinter stehen. @@ -47,6 +58,10 @@ on) echo "Station an: SSID $SSID auf 192.168.8.1, $n Image(s)" echo "Nicht vergessen: 'ninlight-station off', wenn du fertig bist." else + # Mit Restart=always laeuft ein abgestuerzter Dienst sonst im Hintergrund + # weiter in seiner Neustartschleife - erst stoppen, dann den AP runter, + # sonst suggeriert die Meldung unten einen saubereren Zustand als er ist. + sudo systemctl stop ninlight-station 2>/dev/null || true sudo nmcli con down "$AP_CONNECTION" >/dev/null 2>&1 || true echo "Fehler: ninlight-station ist nach dem Start nicht aktiv - Zugangspunkt wieder abgeschaltet. Details: journalctl -u ninlight-station" >&2 exit 1 diff --git a/tools/station/ninlight-station.service b/tools/station/ninlight-station.service index eefa362..04cff98 100644 --- a/tools/station/ninlight-station.service +++ b/tools/station/ninlight-station.service @@ -8,6 +8,14 @@ Description=ninlight recovery station (HTTP image server) # Prozess bei jedem Absturz (z.B. Bind-Fehler nach einem NM-Neustart) per # Restart=always in kurzen Abstaenden neu versuchen lassen. After=network.target NetworkManager.service +# Steht der Zugangspunkt nicht, kann server.py 192.168.8.1 nicht binden und +# stirbt sofort; Restart=always versucht es alle RestartSec=2 erneut. Damit +# das nicht endlos das Journal flutet, sondern nach kurzer Zeit ehrlich +# aufgibt (und ninlight-station dann mit einer klaren Fehlermeldung reagieren +# kann statt in einer stillen Neustartschleife zu haengen), hier explizit +# gedeckelt statt sich auf systemds Vorgabewerte zu verlassen. +StartLimitIntervalSec=30 +StartLimitBurst=5 [Service] Type=simple