Systemd-Dienst wird manuell gestartet, aber nicht beim Booten?

4

Ich habe einen systemd-Dienst geschrieben, um die Bodensteuerung auf meinem Raspberry Pi zu starten.

[Unit]
Description=Groundcontrol status monitor

[Service]
ExecStart=/opt/groundcontrol/groundcontrol/start.sh
Type=forking

[Install]
WantedBy=multi-user.target  

Ich verwende das Skript, da groundcontrol nicht ordnungsgemäß funktioniert, wenn es nicht aus dem bin-Verzeichnis gestartet wird. Hier ist das Skript:

cd /opt/groundcontrol/groundcontrol
./groundcontrol &

Dies funktioniert perfekt, wenn ich es manuell starte, aber wenn ich mein Pi hochlasse und renne systemctl es sagt, dass es fehlgeschlagen ist. systemctl status groundcontrol.service druckt

groundcontrol.service - Groundcontrol status monitor
   Loaded: loaded (/etc/systemd/system/groundcontrol.service; enabled)
   Active: failed (Result: exit-code) since Wed 1969-12-31 17:00:14 MST; 43 years 11 months ago
  Process: 111 ExecStart=/opt/groundcontrol/groundcontrol/start.sh (code=exited, status=0/SUCCESS)
 Main PID: 116 (code=exited, status=2)

Dec 31 17:00:11 waldo systemd[1]: Starting Groundcontrol status monitor...
Dec 31 17:00:12 waldo systemd[1]: Started Groundcontrol status monitor.
Dec 31 17:00:14 waldo systemd[1]: groundcontrol.service: main process exited, code=exited, status=2/INVALIDARGUMENT
Dec 31 17:00:14 waldo systemd[1]: Unit groundcontrol.service entered failed state. 

Wenn ich es manuell starte, ist der Status

groundcontrol.service - Groundcontrol status monitor
   Loaded: loaded (/etc/systemd/system/groundcontrol.service; enabled)
   Active: active (running) since Thu 2013-12-26 15:38:02 MST; 1s ago
  Process: 296 ExecStart=/opt/groundcontrol/groundcontrol/start.sh (code=exited, status=0/SUCCESS)
 Main PID: 297 (groundcontrol)
   CGroup: /system.slice/groundcontrol.service
           `-297 ./groundcontrol

Dec 26 15:38:02 waldo systemd[1]: Started Groundcontrol status monitor. 

Mit groundcontrol wurde ein System V-Init-Skript bereitgestellt, aber ich wusste nicht, wie es mit systemd verwendet werden sollte. Wenn nicht, wie kann ich diesen Service beheben? Vielen Dank.

Lily Hahn
quelle
Du musst verstehen groundcontrol und seine Anforderungen, damit Sie es beim Bootvorgang richtig bestellen können.
Pavel Šimerda

Antworten:

4

Die Protokolle sagen:

main process exited, code=exited, status=2/INVALIDARGUMENT

Das heißt, das Problem liegt bei groundcontrol selbst; Es hat den Status 2 (eine Art Fehler) zurückgegeben.

Normalerweise wird dieses spezielle Problem - Dienst schlägt nur beim Start fehl - durch das Starten des Dienstes verursacht zu früh Das heißt, wenn ein Hardwaregerät erforderlich ist, das vom System noch nicht erkannt wurde. (Denken Sie daran, dass auf modernen Linux-Systemen praktisch alle Geräte dynamisch erkannt werden Nein Punkt, wo es sagt "oh, ich habe alle Geräte, lass uns init beginnen.")

Die Lösung wäre, das Programm neu zu schreiben, um libudev zu verwenden und Geräte dynamisch hinzuzufügen.

Die Problemumgehung besteht darin, den Dienst nach dem spezifischen Gerät zu bestellen (ich weiß jedoch nicht, welches Gerät es benötigt, daher kann ich keine vollständige Antwort geben) oder Wants = + After = verwenden, um das Gerät zu aktivieren systemd-udev-settle.service der wartet, bis udev die erste Charge von "new device" -Ereignissen verarbeitet hat.


Warum haben Sie ein ganzes Ganzes? .sh Skript zum alleinigen Zweck der CD in ein Verzeichnis? WorkingDirectory= + Type=simple würde genügen. (Das & ist auch nicht notwendig, da systemd selbst - als Service Manager - alles im "Hintergrund" ausführt.)

grawity
quelle
1
In dem mitgelieferten Init-Skript (es war für Upstart, also konnte ich es nicht verwenden), hatte es es getan # Required-Start: $local_fs $network $remote_fs. Bedeutet das, dass ich vor dem Start nach den Geräten local_fs, network und remote_fs suchen muss? Gibt es eine Möglichkeit, dies im init-Job zu tun, oder verwende ich einfach After =?
Lily Hahn
Ich fügte hinzu Requires=systemd-udev-settle.service After=systemd-udev-settle.service und es scheint, als hätte es den ganzen Weg nach oben begonnen und dann versagt. Hier ist der Status: pastebin.com/kYietiVA
Lily Hahn
Bearbeiten Sie die Frage, anstatt Paste-Services zu verwenden. Das kannst du einfach sed 's/^/ / die Zeilen, damit sie in einem vorformatierten Block erscheinen.
Pavel Šimerda