Startreihenfolge von Diensten bei Systemd und klassischem Init

Dalai

Grand Admiral Special
Mitglied seit
14.06.2004
Beiträge
7.420
Renomée
262
Standort
Meiningen, Thüringen
Hallo in die Runde, sowie ein gesundes und erfolgreiches neues Jahr an alle!

Aktuell bin ich dabei, privat einige Dienste auf Linux umzuziehen. Ich bin mit den derzeit relevanten Diensten im Prinzip schon durch, aber bei einer Sache weiß ich nicht so recht, wo und wie ich ansetzen muss. Konkret muss ich einen Dienst (Openfire), der nur ein klassisches Init-Skript mitbringt, von MySQL bzw. MariaDB abhängig machen. Es soll sichergestellt werden, dass Openfire beim Booten erst nach MySQL/MariaDB startet, und beim Herunterfahren/Neustart die ganze Geschichte natürlich umgekehrt, also erst Openfire beenden bevor MySQL gestoppt wird.

Das Ganze findet auf einem Debian 10.x (Buster) statt. Was mich wundert, ist die Tatsache, dass MariaDB sowohl eine Systemd-Unit als auch ein klassisches Init-Skript mitbringt, das auch in /etc/rc?.d verlinkt wird.

Kann mir jemand sagen, wo ich ansetzen muss, oder die richtigen Suchbegriffe nennen, mit denen ich weiterkomme? Das wäre klasse.

Grüße
Dalai
 
Inzwischen hab ich einen gangbaren Weg gefunden. Offenbar ist es so, dass Systemd die klassischen Init-Skripte jedes Mal beim Booten analysiert und daraus eine Unit in /run/systemd/generator.late generiert. Es gibt also sozusagen für alle Dienste eine Systemd-Unit, auch für solche, die eigentlich keine mitbringen.

Aus der generierten Unit hab ich die für mich relevanten Angaben rausgeholt, Dopplungen entfernt, und die Abhängigkeit zu MySQL ergänzt. Das Ergebnis hab ich in eine separate Datei /etc/systemd/system/openfire.service.d/dependency.conf gepackt:
Code:
[Unit]
Before=
Before=multi-user.target
After=
After=local-fs.target remote-fs.target network-online.target syslog.service mysql.service
Wants=network-online.target

[Service]
TimeoutSec=2min
Der Dateiname der .conf ist letztlich egal (der Pfad aber nicht).

Bisher hat sich der Openfire nicht mehr beschwert, dass er einige Sekunden keinen Zugriff auf den DB-Server hat. Und beim Herunterfahren scheint er auch vor dem MySQL angehalten zu werden. Schick, aber dennoch werd ich nicht warm mit Systemd.

Grüße
Dalai
 
Es gibt schon Möglichkeiten harte Abhängigkeiten in systemd Units zu packen, aber generell wird davon ausgegangen, dass das nicht notwendig ist.
In deinem Fall scheint der Dienst ja auch zu funktionieren, hat nur einige Sekunden lange keinen Zugriff (was ja nicht prinzipiell schlimm ist, oder?).
Letztendlich sollte es aber schon funktionieren, wenn du das bei Before=/After= in der einen oder der anderen Unit rein packst.

Ich würde dir in dem Fall aber einfach empfehlen für Openfire eine systemd Unit zu erstellen und die statt des Shell Skripts zu nutzen. Ist zum Einen übersichtlicher und zum anderen umgehst du damit dann einen Teil deines Problems.
Irgendwo ist mir auch unklar, warum die überhaupt noch ein Shell Skript mitliefern.
 
In deinem Fall scheint der Dienst ja auch zu funktionieren, hat nur einige Sekunden lange keinen Zugriff (was ja nicht prinzipiell schlimm ist, oder?).
Der Dienst versucht mehrere Sekunden lang, den MySQL-Server zu erreichen. Solange er das nicht kann, meckert er das im Log mit entsprechenden Meldungen (Java-Exceptions?) an. Wenn alles sauber funktioniert, will ich keine Fehlermeldungen in Logs haben, denn sowas irritiert nur, insbesondere beim Auftreten von echten Problemen.

Letztendlich sollte es aber schon funktionieren, wenn du das bei Before=/After= in der einen oder der anderen Unit rein packst.
Naja, das hab ich jetzt ja, indem ich einige Angaben aus der generierten Unit mit den oben geposteten .conf überschrieben/überstimmt habe.

Ich würde dir in dem Fall aber einfach empfehlen für Openfire eine systemd Unit zu erstellen und die statt des Shell Skripts zu nutzen.
Kann man machen, aber das ist mir zuviel Aufwand.

Irgendwo ist mir auch unklar, warum die überhaupt noch ein Shell Skript mitliefern.
Vielleicht aus Kompatibilitätsgründen. Klassische Init-Skripte gehen eben überall.

Grüße
Dalai
 
Kann man machen, aber das ist mir zuviel Aufwand.
Ist nicht sonderlich viel Aufwand.

Zudem kann man sich ja auch bei anderen Distributionen bedienen und das für seine eigenen Zwecke anpassen. z.B.:
(Speziell die Pfade muss man ggf. anpassen, da hat ja jede Distribution etwas andere Dateisystemlayouts.)

Ich persönlich bin ein großer Fan von den unit Dateien. Sind wesentlich übersichtlicher und nachvollziehbarer als die shell Skripte. Die gingen mir schon zu SysV init / OpenRC Zeiten auf den Zeiger, da es immer wieder mal zu Problemen kam und man dann Stunden damit verbracht hat herauszufinden an welcher Stelle im Skript nun das ganze Amok läuft (in einem Fall ist es mir sogar nie gelungen).

Leider ist bei systemd auch nicht alles golden was glänzt, aber zumindest den einen Schritt fand ich super.
 
Du kannst das ja auch mal mit Devuan Beowulf = Debian Buster - systemd probieren. Da gehen normale Init-Skripte.

Rolf
 
Ist nicht sonderlich viel Aufwand.
Doch, ist es, vor allem für jemanden, der gerade erst anfängt, sich mit Systemd zu beschäftigen. Es geht ja schon damit los, dass das Init-Skript eine Suche nach einem ("dem besten") Java macht, bevor es den Dienst startet, alternativ aber auch ein Java an nutzerdefinierter Stelle nutzen kann. Ich werde das jetzt erstmal so lassen, bis es einen Grund gibt, es zu ändern. Ob es stabil funktioniert, wird sich in den kommenden Tagen zeigen, wenn ich das Openfire auf meinem neuen Raspi installiere - ich gehe aber davon aus.

Du kannst das ja auch mal mit Devuan Beowulf = Debian Buster - systemd probieren. Da gehen normale Init-Skripte.
Ich hatte darüber nachgedacht, eine Distri ohne Systemd zu nutzen, aber da in der Firma ein Ubuntu läuft, muss ich mich sowieso mit Systemd auseinandersetzen. Allerdings versuche ich, das auf das Allernötigste zu reduzieren, denn mich nervt der Wechsel des Init-Systems alle drei bis vier Jahre: im Ubuntu 8 nur SysV, dann im Ubuntu 12 Upstart und ab Ubuntu 16 ist es Systemd. Was kommt dann 2022?

Da mein Ziel ist, das Openfire auf einem Raspi laufen zu lassen, hab ich da eh keine so freie Wahl der Distribution wie auf einem PC. Das konntest du natürlich nicht wissen, denn bisher hab ich das hier nicht erwähnt, weil die Idee mit dem Raspi einerseits erst vor wenigen Wochen kam und andererseits dieses Detail von untergeordneter Bedeutung ist.

Grüße
Dalai
 
Ist nicht sonderlich viel Aufwand.
Doch, ist es, vor allem für jemanden, der gerade erst anfängt, sich mit Systemd zu beschäftigen. Es geht ja schon damit los, dass das Init-Skript eine Suche nach einem ("dem besten") Java macht, bevor es den Dienst startet, alternativ aber auch ein Java an nutzerdefinierter Stelle nutzen kann.
Das hat da aber auch eigentlich überhaupt nichts verloren und erhöht nur völlig unnötigerweise die Komplexität.
Wie man hier bei systemd vorgehen würde? Nun, die Distribution sollte eine unit mitbringen, welche für die typische Standardkonfiguration der Distribution funktioniert.
Du willst einen benutzerdefinierten Pfad zu deinem Programm oder einem anderen was das nutzt?
Dann kopiert man einfach die Standrad Unit von /usr/lib/systemd/system nach /etc/systemd/system und passt sie so an, dass sie den eigenen Bedürfnissen genügt.
Da die Units sehr übersichtlich und einfach gehalten sind ist das normalerweise auch kein Problem und schnell erledigt.
Hat zudem den Vorteil, dass man auch selbst nachvollziehen kann was die Unit macht. Wenn die Unit dann mit gleichem Dateinamen in /etc liegt, dann hat die auch Priorität und wird genutzt.
So maskiert man übrigens auch Units um sicherzustellen, dass systemd sie niemals startet, indem man einen Link mit gleichem Namen auf /dev/null ablegt, z.B.:
Code:
ll /etc/systemd/system/systemd-coredump@.service 
lrwxrwxrwx 1 root root 9 May  3  2018 /etc/systemd/system/systemd-coredump@.service -> /dev/null

Tatsächlich ist es vermutlich so, dass gerade die Komplexität der Shell Skripte dazu geführt hat, dass das solche Blüten trägt wie das was du da erwähnt hast, da man es nicht mehr verantworten konnte dem Admin die Modifikation der Skripte zu überlassen, zu groß war das Risiko, dass dabei Bugs eingeführt werden.

Ich kann aber natürlich auch verstehen, dass neue Konzepte erst mal überfordern, insofern kann ich dein Vorgehen nachvollziehen.
Genau daher hatte ich dich aber auch auf entsprechende Unit Dateien aus anderen Distributionen hingewiesen.
Genau das ist nämlich auch ein extrem großer Vorteil von systemd, dass es die Eingangsdateien des Init Systems deutlich vereinheitlicht hat.
Sys V Init zwischen Distributionen auszutauschen war im Grunde undenkbar, bei systemd Units geht das in vielen Fällen problemlos, hier und da muss man evtl. noch Pfade anpassen, aber das ist im Normalfall kein Problem, man kann ja nach den entsprechenden Dateien suchen (bzw. sich die Dateiliste der entsprechenden Pakete ausgeben lassen).
Man muss für solche Units also so gut wie nie bei Null anfangen, hab ich selbst glaube ich auch nur 2-3 mal gemacht.
Allerdings versuche ich, das auf das Allernötigste zu reduzieren, denn mich nervt der Wechsel des Init-Systems alle drei bis vier Jahre: im Ubuntu 8 nur SysV, dann im Ubuntu 12 Upstart und ab Ubuntu 16 ist es Systemd. Was kommt dann 2022?
Da hätte ich wenig Bedenken. Das Thema ist durch. systemd ist der neue Standard und wird es auf absehbare Zeit auch bleiben.
Es ist sicher nicht perfekt und sorgt (manchmal auch wirklich zurecht) hier und da für Kritik, aber im Grunde sind die meisten wohl auch einfach froh die Sys V Init Zeit hinter sich zu haben.

Ich persönlich bin auch nicht mit allem zufrieden. z.B. wie mounts gehandhabt werden ist auf meinem System immer wieder mal sehr nervig.
z.B. ist es zumindest früher (?) passiert, dass systemd ein mount das man gerade als root eingehängt hatte (ne Backup Platte o.ä.) direkt wieder ausgehängt wurde, weil es nicht in fstab eingetragen war. So komisches Zeug halt …
Mittlerweile funktioniert es aber eigentlich ziemlich gut und manche der Änderungen die systemd über die Zeit mitgebracht hat empfinde ich inzwischen als deutliche Verbesserung. Vor allem das journal (da gab es ja auch sehr viel Kritik), da die Abfrage der Logs über journalctl einfach so viel besser und angenehmer ist als alles was man vorher hatte. So muss ich, wenn ich z.B. wissen wollte welche btrfs Meldungen es seit dem letzten Bootvorgang gab nur aufrufen:
Code:
journalctl -b 0 -g btrfs
(oder lang)
Code:
journalctl --boot=0 --grep=btrfs

Und wenn ich dann nur Fehler haben wollte:
Code:
journalctl --boot=0 --grep=btrfs --priority=err

Im syslog nach btrfs zu greppen wäre natürlich auch gegangen, aber bei den anderen beiden Dingen wird es schon deutlich schwerer. Ok, nach "error" greppen geht sicher auch noch, aber es ist hier halt schon sehr hilfreich, dass journalctl nicht nur auf den eingetragenen Text Zugriff hat, sondern auch noch zusätzliche Tags, Statuseinträge etc.

Auch die integrierten resolved, networkd und timesyncd ziehe ich inzwischen den Alternativen vor, aber das ist sicher auch Geschmackssache, aber man kann da ja wählen was man nutzen will. ;)
 
Zurück
Oben Unten