FHEM Forum

FHEM - Hardware => Server - Linux => Thema gestartet von: a-p-s am 03 März 2018, 23:05:27

Titel: FHEM über systemd mit Watchdog und sd_notify
Beitrag von: a-p-s am 03 März 2018, 23:05:27
Hallo zusammen,

aufbauend auf den Diskussionen hier zum Thema systemd hatte ich ein paar Experimente gemacht, um meine FHEM-Installationen etwas stabiler zu machen, ohne die Komplexität hochzuschrauben. Dafür habe ich die systemd-Bordmittel (Watchdog) genutzt.

Hier die resultierende Service Unit:

[Unit]
Description=FHEM Home Automation
Requires=network.target
After=dhcpcd.service

[Service]
Type=notify
NotifyAccess=all
User=fhem
Group=dialout
WorkingDirectory=/opt/fhem
ExecStart=/usr/bin/perl fhem.pl fhem.cfg
TimeoutStartSec=240
TimeoutStopSec=120
ExecStop=/usr/bin/pkill -U fhem perl
Restart=always
RestartSec=10
WatchdogSec=180
PIDFile=/opt/fhem/log/fhem.pid
 
[Install]
WantedBy=multi-user.target

Um den Watchdog zu nutzen, muss man aus FHEM regelmäßige Nachrichten über ein UNIX-Socket schicken (sd_notify). Da die Bibliotheken, die ich gefunden habe, ultra-heavy sind für den simplen Task, ist das hier schnell zusammengeschrieben:

attr global nofork 1

defmod systemd_ready notify global:INITIALIZED { \
use Socket;;;;\
my $name = $ENV{NOTIFY_SOCKET};;;;\
my $sock_addr = sockaddr_un($name);;;;\
socket(my $server, PF_UNIX,SOCK_DGRAM,0);;;;\
connect($server, $sock_addr);;;;\
print $server "READY=1\n";;;;\
close($server);;;; }

defmod systemd_shutdown notify global:SHUTDOWN {\
use Socket;;;;\
my $name = $ENV{NOTIFY_SOCKET};;;;\
my $sock_addr = sockaddr_un($name);;;;\
socket(my $server, PF_UNIX,SOCK_DGRAM,0);;;;\
connect($server, $sock_addr);;;;\
print $server "STOPPING=1\n";;;;\
close($server);;;; }

defmod systemd_watchdog at +*00:01 { \
use Socket;;;;\
my $name = $ENV{NOTIFY_SOCKET};;;;\
my $sock_addr = sockaddr_un($name);;;;\
socket(my $server, PF_UNIX,SOCK_DGRAM,0);;;;\
connect($server, $sock_addr);;;;\
print $server "WATCHDOG=1\n";;;;\
close($server);;;; }

Das funktioniert bei mir seit einer Weile ganz gut. Mit den Timeouts muss man ein bisschen spielen. Eine meiner Installationen ist da (zeitweise) etwas träge, so dass ich die Timeouts hochgesetzt habe.

Momentan ist das noch ein Hack - da kann man ein Modul draus bauen.

Vielleicht kann trotzdem jemand etwas damit anfangen.

Grüße,
a-p-s
Titel: Antw:FHEM über systemd mit Watchdog und sd_notify
Beitrag von: hexenmeister am 04 März 2018, 10:39:51
ich baue mal kurz ein Modul daraus...
Titel: Antw:FHEM über systemd mit Watchdog und sd_notify
Beitrag von: hexenmeister am 04 März 2018, 17:43:14
So, hier wäre das. Richtig testen konnte ich noch nicht, muss zuerst mein Test-FHEM auf systemd-script umstellen.
Datei in FHEM-Verzeichnis werfen und Device anlegen.
define watchdog systemd_watchdog
EDIT: Anhang gelöscht
Titel: Antw:FHEM über systemd mit Watchdog und sd_notify
Beitrag von: hexenmeister am 04 März 2018, 18:57:59
Habe ein Fehler mit dem InternalTimer gefunden (lief nach dem Löschen von Modul, mit aktivierten Watchdog sollte man das Modul eh jedoch besser nicht löschen).
Titel: Antw:FHEM über systemd mit Watchdog und sd_notify
Beitrag von: hexenmeister am 04 März 2018, 19:32:13
Vorerst endgültige Version (nur Commandref geschrieben).
Habe zwischendurch testen können.  Benutze Type=forking mit einer PIDFile. Funktioniert bis jetzt sehr gut. Shutdown klappt (Restart=allways durch Restart=on-failure ersetzt). Nach dem kill -9 wird korrekt neu gestartet.
Titel: Antw:FHEM über systemd mit Watchdog und sd_notify
Beitrag von: a-p-s am 04 März 2018, 20:11:12
Das ging ja super schnell. Danke!

Habe meine Bastellösung durch das Modul ausgetauscht (blieb also bei Type=Notify). Funktioniert bislang einwandfrei.

Grüße,
a-p-s
Titel: Antw:FHEM über systemd mit Watchdog und sd_notify
Beitrag von: hexenmeister am 04 März 2018, 20:39:36
Das ging ja super schnell. Danke!
Gerne. Deine Bastellösung ersparte mir die Suche und Einarbeitung um meine Bastellösung zu ersetzen. win-win ;)
Titel: Antw:FHEM über systemd mit Watchdog und sd_notify
Beitrag von: hexenmeister am 04 März 2018, 21:21:31
Kurzanleitung für die Verwendung:



[Unit]
Description=FHEM Home Automation
Requires=network.target
#After=network.target
After=dhcpcd.service

[Service]
Type=forking
NotifyAccess=all
User=fhem
Group=dialout
WorkingDirectory=/opt/fhem
ExecStart=/usr/bin/perl fhem.pl fhem.cfg
#ExecStart=/usr/bin/perl fhem.pl configDB
TimeoutStartSec=240
TimeoutStopSec=120
#ExecStop=/usr/bin/pkill -U fhem perl
ExecStop=/usr/bin/pkill -f -U fhem "fhem.pl fhem.cfg"
# Restart options: no, on-success, on-failure, on-abnormal, on-watchdog, on-abort, or always.
Restart=on-failure
RestartSec=3
WatchdogSec=180
PIDFile=/opt/fhem/log/fhem.pid

[Install]
WantedBy=multi-user.target

Das Modul erzeugt zwei Readings:
state: gibt an, ob die Instanz aktiv ist (ist automatish der Fall, wenn Systemd-Watchdog verfügbar ist)
next: zeigt den Zeitpunkt der nächten keep-alive-Meldung

Außerdem gibt es zusützlich zu den allgemeinen 'Internals' zwei weitere:
sleep-time: Zeitinterval zw. den keep-alive-Meldungen (wird aus dem im Watchdog definierten Interval ausgerechnet, es wird ein Vietel von der maximalen Zeit verwendet).
systemd-watchdog: zeigt an, ob Systemd-Watchdog verfügbar ist.
Titel: Antw:FHEM über systemd mit Watchdog und sd_notify
Beitrag von: hexenmeister am 14 März 2018, 22:00:39
Habe jetzt das Modul ein paar Tage getestet, für stabil befunden und letztendlich in contib eingecheckt.
Titel: Antw:FHEM über systemd mit Watchdog und sd_notify
Beitrag von: tpm88 am 15 März 2018, 22:59:05
Hallo Alexander,

Kurzanleitung für die Verwendung:

  • Prüfen, ob alles wie gewünscht funktioniert: FHEM wird nicht alle 3 Minuten durch den Watchdog gekillt, beim Beenden mittels kill -9 wird neu gestartet, bei shutdown (aus FHEM) jedoch nicht.


Ich habe den watchdog exakt nach obiger Kurzanleitung definiert.

Er funktioniert soweit einwandfrei - allerdings wird fhem auch bei einem shutdown (aus FHEM) neu gestartet - trotz:
Restart=on-failure
Hier ein paar relevante Zeilen aus dem fhem.log:

2018.03.15 22:40:31 0: Server shutdown
2018.03.15 22:40:31 1: Timeout for SIP_ListenStart reached, terminated process 30235
2018.03.15 22:40:31 2: Watchdog Client: Shutting down
2018.03.15 22:40:31 2: Watchdog Client: deactivated
2018.03.15 22:40:35 3: [UtilsHourCounter] Init Done with Version 1.0.1.0 - 10.12.2014 (john)
2018.03.15 22:40:36 1: PERL WARNING: "my" variable $url masks earlier declaration in same scope at ./FHEM/99_myUtils.pm line 371.
2018.03.15 22:40:36 1: Including fhem.cfg
2018.03.15 22:40:36 3: telnetPort: port 7072 opened
...
2018.03.15 22:40:53 2: Watchdog Client: initialized
2018.03.15 22:40:53 3: OWS_rpi1: Opening connection to OWServer 192.168.8.52:4304...
2018.03.15 22:40:53 3: OWS_rpi1: Successfully connected to 192.168.8.52:4304.
2018.03.15 22:40:54 1: PERL WARNING: Use of uninitialized value in split at ./FHEM/10_OWServer.pm line 395.
2018.03.15 22:40:54 0: [Freezemon] fm: Log3 is already wrapped
2018.03.15 22:40:54 0: [Freezemon] fm: status=already wrapped
2018.03.15 22:40:54 2: [Freezemon] fm ready to watch out for delays greater than 1 second(s)
2018.03.15 22:40:54 3: NTFY return:  watchdog:active
2018.03.15 22:40:54 0: Featurelevel: 5.8
2018.03.15 22:40:54 0: Server started with 201 defined entities (fhem.pl:16403/2018-03-13 perl:5.020002 os:linux user:fhem pid:30427)

Hast du eine Idee?

Gruß
Tobias
Titel: Antw:FHEM über systemd mit Watchdog und sd_notify
Beitrag von: hexenmeister am 16 März 2018, 22:25:42
Ich weiß nicht, was ich damals getestet habe ??? War wohl schon zu spät... Wie auch immer, jetzt tut es bei mir auch nicht - es startet immer neu. Möglicherweise liefert FHEM nie den Wert für 'efolgreich beendet' zurück. Muss ich mir mal genauer ansehen.
 >:(
Titel: Antw:FHEM über systemd mit Watchdog und sd_notify
Beitrag von: Funsailor am 02 Januar 2019, 18:06:04
Hallo Alexander,
ist der von tpm88 gemeldete Fehler mit dem shutdown mit deiner Version
17206 2018-08-25 18:18:49
gefixt?
Titel: Antw:FHEM über systemd mit Watchdog und sd_notify
Beitrag von: hexenmeister am 02 Januar 2019, 22:09:05
Der Fehler bezieht sich noicht auf das Modul, das funktioniert richtig. Der systemd-Script müsste irgendwie angepasst werden, da bin ich jedoch kein Experte. Für meine Zwecke ist es nur wichtig, dass es sicher neugestartet wird. Wenn jemand eine Lösung hat, werde ich sie entsprechend im Commandref beschreiben.
Derzeit funktioniert es bei mir genau andersrum: 'shutdown' bewirkt einen Restart und 'shutdown restart' beendet FHEM.
Titel: Antw:FHEM über systemd mit Watchdog und sd_notify
Beitrag von: Funsailor am 03 Januar 2019, 11:56:19
Hallo Alexander,
ich habe den Wdt gestern nach deiner Anleitung eingebaut (vorher hatte ich schon auf Systemctl.umgestellt, das lief gut durch)
Wenn ich in global norfork =>1 setze, fährt mir fhem regelmäßig herunter. Angeblich sendet mein (in der Liste erstes) fronthem device ein Shutdown....
Muss bei Gelegenheit weitersuchen, bin jetzt unterwegs. Aber falls jemand eine Idee hat..... wäre gut.
Danke....
Titel: Antw:FHEM über systemd mit Watchdog und sd_notify
Beitrag von: Gisbert am 25 März 2019, 16:24:00
Hallo Alexander, Funsailor und a-p-s,

gibt es einen Fortschritt in dieser Sache? Ich wäre interessiert es einzusetzen.
Ich möchte gerne eine stabile Lösung, die ich mit meinen laienhaften Kenntnissen umsetzen kann.

Meine Erfahrungen mit unterschiedlichen Ansätzen zum Neustart von Fhem und/oder des Servers sind ernüchternd, es ist nicht auszuschließen, dass es an mir lag:
- Einen Neustart habe ich bisher nicht wissentlich registriert.
- Dafür war die Überwachung selbst zweimal die Ursache, warum entweder Fhem nicht mehr gestartet werden konnte oder den Server im Minutentakt neu gestartet hat.

Folgender Weg über systemd mit Watchdog funktioniert leider nicht.
Auszug Service Unit:
WatchdogSec=120s
StartLimitInterval=5min
StartLimitBurst=4
StartLimitAction=reboot-force
Definition in Fhem:
defmod heartbeat at +*00:01:00 {qx(systemd-notify WATCHDOG=1)}Ergebnis ist, dass Fhem alle 120 Sekunden neu gestartet wird - d.h. an und für sich geht der Watchdog.
Allerdings macht der Befehl in Fhem nichts sinnvolles, nämlich einen Neustart von Fhem zu verhindern, wenn es noch läuft.

Viele Grüße Gisbert