FHEM Forum

FHEM => Sonstiges => Thema gestartet von: vbs am 05 Dezember 2015, 18:51:49

Titel: Problem bei "shutdown restart" / Anpassung Exit Code
Beitrag von: vbs am 05 Dezember 2015, 18:51:49
Ich sitze gerade dran, FHEM bei mir als systemd-Dienst laufen zu lassen.  Und zwar hab ich FHEM als "forking" konfiguriert und geben das PID-File von FHEM beim systemd an. systemd bietet ja auch eine Prozessüberwachung und kann dann FHEM neu starten im Falle eines Absturzes.

Das sieht dann im Moment so aus:
[Service]
Type=forking
User=fhem
Restart=on-failure
PermissionsStartOnly=true
PIDFile=/var/run/fhem/fhem.pid
WorkingDirectory=/media/fhem
ExecStartPre=-/bin/mkdir /var/run/fhem
ExecStartPre=/bin/chown -R fhem /var/run/fhem
ExecStart=/usr/bin/perl fhem.pl fhem-vbs.cfg


Das klappt soweit auch alles ganz gut. Ich kann starten und beenden und auch wenn ich FHEM mit SIGKILL abschieße, wird es sauber von systemd neu gestartet. Das Problem ist aber nun das Verhalten bei "shutdown restart": Wenn ich das eingebe, verschwindet der FHEM-Prozess und es wird kein neuer gestartet (weder von FHEM selbst, noch von systemd).

Ich vermute, dass es daran liegt, dass der User "fhem" als welcher der FHEM-Prozess läuft, bei mir keine zugeordnete Shell hat (brauchen ja Daemon-User normalerweise nicht). Aber FHEM ruft dann bei "shutdown restart" auf:
system("(sleep " . AttrVal("global", "restartDelay", 2) .
                                 "; exec $^X $0 $attr{global}{configfile})&");
exit(0);


Aus Sicht von systemd wiederum, hat sich der FHEM-Prozess sauber mit ExitCode 0 beendet. Also kein Grund zum Neustart.

Sind also eigentlich zwei Probleme:
- Zum einen denke ich, dass der momentane Neustart-Mechanismus von FHEM nicht mit einem shell-losen Benutzer klar kommt
- Zum anderen die saubere Einbindung in init-Dienste wie zB systemd

Hat schon jemand eine Lösung für sowas?

Solche Sachen sind ja recht OS/Distributions-spezifisch. Eine Möglichkeit wäre mMn, diese Restart-Logik aus FHEM auszulagern. Zum Beispiel könnte man ein Attribut machen, dass bewirkt, dass sich FHEM im Falle von "shutdown restart" nicht selbst neu startet, sondern sich einfach nur beendet. Jedoch dann nicht mit Exit Code 0, sondern etwas ungleich 0, was dann der Prozessüberwachung einen gewünschten Neustartet signalisiert. Bei einem normalen "shutdown" ändert sich nichts: Einfach beenden mit ExitCode 0.

Ich würde mich natürlich auch anbieten, sowas einzbauen. Würde aber erstmal gerne abklären, ob es dafür schon andere Lösungen/Ideen gibt.
Titel: Antw:Problem bei "shutdown restart" / Anpassung Exit Code
Beitrag von: rudolfkoenig am 05 Dezember 2015, 19:16:07
define myShutdown cmdalias shutdown restart AS { exit(1) }
Titel: Antw:Problem bei "shutdown restart" / Anpassung Exit Code
Beitrag von: vbs am 05 Dezember 2015, 20:19:08
Ok, so kann mans auch machen. Reicht aber für mich aus, danke!
Titel: Antw:Problem bei "shutdown restart" / Anpassung Exit Code
Beitrag von: ok am 10 Dezember 2015, 12:45:25
Bei mir läuft seit 1-2 Monaten folgendes UNIT-File ohne Probleme (auf eines RasPi mit jessie):

[Unit]
Description=FHEM Perl Server
After=syslog.target network.target

[Service]
Type=oneshot
RemainAfterExit=yes
User=fhem
Group=fhem
WorkingDirectory=/opt/fhem
ExecStart=/usr/bin/perl /opt/fhem/fhem.pl /opt/fhem/fhem.cfg
ExecStop=/usr/bin/perl /opt/fhem/fhem.pl 7072 shutdown
ExecReload=/usr/bin/perl /opt/fhem/fhem.pl 7072 shutdown;/usr/bin/perl /opt/fhem/fhem.pl /opt/fhem/fhem.cfg;

[Install]
WantedBy=multi-user.target

Titel: Antw:Problem bei "shutdown restart" / Anpassung Exit Code
Beitrag von: vbs am 10 Dezember 2015, 14:30:03
Der springende Punkt ist ja der automatische Neustart von FHEM. Das ist in deinem Script nicht drin, oder?
Titel: Antw:Problem bei "shutdown restart" / Anpassung Exit Code
Beitrag von: vbs am 21 Dezember 2015, 12:13:00
Kann es sein, dass bei der vorgeschlagenen Methode beim Aufruf von exit(1) keine state-Files und co. mehr geschrieben werden? Ich hab das Gefühl, dass seitdem ich das mit der Methode mache, mein state beim Restart irgendwie nicht mehr derselbe ist wie vorher :(
Es wird doch der gesamte FHEM-Shutdown-Vorgang übersprungen, der bei einem "echten" Shutdown durchlaufen wird, oder?

sub
CommandShutdown($$)
{
  my ($cl, $param) = @_;
  return "Usage: shutdown [restart]"
        if($param && $param ne "restart");

  DoTrigger("global", "SHUTDOWN", 1);
  Log 0, "Server shutdown";

  foreach my $d (sort keys %defs) {
    CallFn($d, "ShutdownFn", $defs{$d});
  }

  WriteStatefile();
  unlink($attr{global}{pidfilename}) if($attr{global}{pidfilename});
  if($param && $param eq "restart") {
    if ($^O !~ m/Win/) {
      system("(sleep " . AttrVal("global", "restartDelay", 2) .
                                 "; exec $^X $0 $attr{global}{configfile})&");
    } elsif ($winService->{AsAService}) {
      # use the OS SCM to stop and start the service
      exec('cmd.exe /C net stop fhem & net start fhem');
    }
  }
  exit(0);
}
Titel: Antw:Problem bei "shutdown restart" / Anpassung Exit Code
Beitrag von: rudolfkoenig am 21 Dezember 2015, 13:44:22
exit() macht genau das, und nicht mehr.
Ich habe shutdown mit dem optionalen exit Wert erweitert, Syntax waere:
Zitatshutdown 1
Titel: Antw:Problem bei "shutdown restart" / Anpassung Exit Code
Beitrag von: vbs am 21 Dezember 2015, 15:16:07
Klasse, dankeschön!
Titel: Antw:Problem bei "shutdown restart" / Anpassung Exit Code
Beitrag von: Ralli am 25 April 2020, 13:26:20
Zitat von: rudolfkoenig am 05 Dezember 2015, 19:16:07
define myShutdown cmdalias shutdown restart AS { exit(1) }

Ich hole das Thema noch einmal hoch. Ja, ich weiß, es gibt zwischenzeitlich unzählige Threads zu dem Thema "shutdown restart systemd". Und ich habe viele, viele gelesen. Meines Erachtens ist das grundsätzliche Problem aber nicht gelöst.

Nutze ich den cmdalias, funktioniert sowohl ein in fhem durchgeführter shutdown als auch ein shutdown restart, wenn ich in fhem.service restart=on-failure definiert habe. Der einzige Nachteil ist der, dass innerhalb von fhem nicht die Shutdown-Funktion aufgerufen wird sondern direkt ein exit durchgeführt wird - damit ist bspw. auch kein Log des Shutdowns protokolliert.

Wäre es nicht eine Möglichkeit, über ein optionales Attribut in global den Exitcode für den Restart extra definieren zu können und den in der Shutdown-Funktion dann mitzugeben?
Titel: Antw:Problem bei "shutdown restart" / Anpassung Exit Code
Beitrag von: rudolfkoenig am 25 April 2020, 13:51:53
https://fhem.de/commandref_modular.html#shutdown:

Zitatshutdown [restart|exitValue]

Shut down the server (after saving the state information ). It triggers the global:SHUTDOWN event. If the optional restart parameter is specified, FHEM tries to restart itself. exitValue may be important for start scripts.

Example:

    shutdown
    shutdown restart
    shutdown 1
Titel: Antw:Problem bei "shutdown restart" / Anpassung Exit Code
Beitrag von: Ralli am 25 April 2020, 13:58:37
Hallo Rudi,

ja, ich weiß (durch das CmdAlias-Beispiel) - "shutdown 1" macht genau das, was in diesem Kontext erwartet wird. Fhem wird ordentlich beendet, Ausstieg mit Exitcode 1, über systemd wird neu gestartet. So mache ich es auch bei mir.

Aber halt nicht über das "schönere" Kommando "shutdown restart".

Ist nur Optik, nicht Funktionalität. "Schön" wäre, man könnte restart mit einem Exitcode belegen :-).

Edit:
Was natürlich auch geht, ist das von dir verwandte Beispiel abzuwandeln:


define myShutdown cmdalias shutdown restart AS shutdown 1 }
Titel: Antw:Problem bei "shutdown restart" / Anpassung Exit Code
Beitrag von: rudolfkoenig am 25 April 2020, 14:13:55
Mit restart=on-failure und exit 1 bei shutdown restart wird FHEM zweimal gestartet (oder ich uebersehe etwas).

Vor dem Loesungsvorschlag will ich das Problem verstehen.
Titel: Antw:Problem bei "shutdown restart" / Anpassung Exit Code
Beitrag von: Ralli am 25 April 2020, 18:17:00
Nein, kann ich nicht bestätigen.

Ich habe zwei Ubuntu-Systeme mit systemd. Bei beiden beendet fhem grundsätzlich bei einem "shutdown" mit exitcode 0 und bei einem "shutdown restart" genau so.

Mit den Standard-Einstellungen in fhem.service ("restart=always") wird fhem durch systemd immer neu gestartet, egal ob in fhem ein "shutdown" oder ein "shutdown restart" veranlasst wurde. Mit der Einstellung "restart=on-abnormal" oder auch "restart=on-failure" in fhem.service wird fhem bei einem "shutdown" und auch bei "shutdown restart" beendet, vom systemd jedoch nicht neu gestartet, weil der exitcode immer 0 ist. Erst dann, wenn als exitcode nicht 0 übergeben wird, startet systemd bei der Einstellung "restart=on-failure" den fhem-Prozess neu.

Lange Rede, kurzer Sinn, mit anderen Worten: wenn ich aus fhem heraus einen shutdown ohne Restart veranlassen möchte, darf in fhem.service nicht "restart=always" definiert sein. Wennn ich aus fhem heraus aber die Möglichkeit belassen möchte, nicht nur einen shutdown sondern auch einen restart von fhem zu veranlassen, muss ich für systemd über den exitcode unterscheiden.
Titel: Antw:Problem bei "shutdown restart" / Anpassung Exit Code
Beitrag von: rudolfkoenig am 25 April 2020, 18:44:04
Genau so habe ich es auch verstanden.
Bei der systemd Einstellung restart=on-failure fuehrt shutdown zu einem normalen shutdown, und shutdown 1 zu einem restart.
Wenn man das FHEM restart unbedingt mit dem Befehl "shutdown restart" ausloesen will, dann muss man
define myShutdown cmdalias shutdown restart AS shutdown 1
definieren. Soe wie Du es gezeigt hast, bloss ohne }

Alternativ verwendet man die Systemd Voreinstellung restart=no und man muss in FHEM auch nichts umstellen.
Titel: Antw:Problem bei "shutdown restart" / Anpassung Exit Code
Beitrag von: vbs am 25 April 2020, 18:52:04
Zitat von: rudolfkoenig am 25 April 2020, 18:44:04
Alternativ verwendet man die Systemd Voreinstellung restart=no und man muss in FHEM auch nichts umstellen.
Anzumerken, dass in diesem Fall FHEM auch im Falle eines Crashes nicht neu gestartet wird. Da muss man dann händisch tätig werden.
Titel: Antw:Problem bei "shutdown restart" / Anpassung Exit Code
Beitrag von: Ralli am 25 April 2020, 19:02:52
Zitat von: rudolfkoenig am 25 April 2020, 18:44:04
Soe wie Du es gezeigt hast, bloss ohne }

Ja natürlich, sorry, das war ein Übertragungsfehler.

Um das nun zum Abschluss recherchierbar zu machen, ist die folgende Vorgehensweise mit systemd die Lösung:


define myShutdown cmdalias shutdown restart AS shutdown 1


und

/etc/systemd/system/fhem.service:

[Unit]
Description=FHEM Home Automation
Wants=network.target
After=network.target
#Requires=postgresql.service
#After=postgresql.service
#Requires=mysql.service
#After=mysql.service

[Service]
Type=forking
User=fhem
Group=dialout
WorkingDirectory=/opt/fhem
ExecStart=/usr/bin/perl fhem.pl fhem.cfg
#ExecStart=/usr/bin/perl fhem.pl configDB
#Restart=always
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target