Generische Methode zum Debuggen von Bestellzyklen in systemd

23

Mir ist der folgende Thread bekannt und angeblich eine Antwort darauf . Mit der Ausnahme, dass eine Antwort keine generische Antwort ist. Es zeigt, was das Problem in einem bestimmten Fall war, aber nicht im Allgemeinen.

Meine Frage ist: Gibt es eine Möglichkeit, Bestellzyklen generisch zu debuggen ? ZB: Gibt es einen Befehl, der den Zyklus beschreibt und der eine Einheit mit einer anderen verbindet?

Ich habe zum Beispiel Folgendes journalctl -beingegeben (bitte Datum ignorieren, mein System hat keine RTC, mit der die Zeit synchronisiert werden kann):

Jan 01 00:00:07 host0 systemd[1]: Found ordering cycle on sysinit.target/start
Jan 01 00:00:07 host0 systemd[1]: Found dependency on local-fs.target/start
Jan 01 00:00:07 host0 systemd[1]: Found dependency on cvol.service/start
Jan 01 00:00:07 host0 systemd[1]: Found dependency on basic.target/start
Jan 01 00:00:07 host0 systemd[1]: Found dependency on sockets.target/start
Jan 01 00:00:07 host0 systemd[1]: Found dependency on dbus.socket/start
Jan 01 00:00:07 host0 systemd[1]: Found dependency on sysinit.target/start
Jan 01 00:00:07 host0 systemd[1]: Breaking ordering cycle by deleting job local-fs.target/start
Jan 01 00:00:07 host0 systemd[1]: Job local-fs.target/start deleted to break ordering cycle starting with sysinit.target/start

Dabei ist cvol.service (derjenige, der eingeführt wurde und den Zyklus unterbricht):

[Unit]
Description=Mount Crypto Volume
After=boot.mount
Before=local-fs.target

[Service]
Type=oneshot
RemainAfterExit=no
ExecStart=/usr/bin/cryptsetup open /dev/*** cvol --key-file /boot/***

[Install]
WantedBy=home.mount
WantedBy=root.mount
WantedBy=usr-local.mount

Laut journalctl möchte cvol.service basic.service, abgesehen davon, dass dies nicht der Fall ist, zumindest nicht offensichtlich. Gibt es einen Befehl, der zeigt, woher dieser Link stammt? Und im Allgemeinen gibt es einen Befehl, der die Zyklen findet und anzeigt, woher die einzelnen Verknüpfungen im Zyklus stammen?

Galets
quelle

Antworten:

20

Gibt es einen Befehl, der zeigt, woher dieser Link stammt?

Der nächste Schritt ist der systemctl show -p Requires,Wants,Requisite,BindsTo,PartOf,Before,After cvol.service, bei dem die resultierenden (effektiven) Abhängigkeitslisten für eine bestimmte Einheit angezeigt werden.

Gibt es einen Befehl, der die Zyklen findet und anzeigt, woher die einzelnen Verknüpfungen im Zyklus stammen?

Meines Wissens gibt es keinen solchen Befehl. Eigentlich bietet systemd nichts, was beim Debuggen von Bestellzyklen helfen könnte (seufz).

Laut journalctl möchte cvol.service basic.service, abgesehen davon, dass dies nicht der Fall ist, zumindest nicht offensichtlich.

Zunächst werden die Anforderung Abhängigkeiten ( Wants=, Requires=, BindsTo=etc.) sind unabhängig von Ordnungsabhängigkeiten ( Before=und After=). Was Sie hier sehen, ist ein Ordnungsabhängigkeitszyklus , dh er hat nichts mit Wants=usw. zu tun .

Zweitens gibt es eine Reihe von "Standardabhängigkeiten", die zwischen Einheiten bestimmter Typen erstellt werden. Sie werden von der DefaultDependencies=Direktive in dem [Unit]Abschnitt (der standardmäßig aktiviert ist ) gesteuert .

Sofern diese Direktive nicht explizit deaktiviert ist, werden .serviceimplizite Requires=basic.targetund After=basic.targetabhängige Einheiten jedes Typs abgerufen. Dies ist genau das, was Sie sehen. Dies ist in systemd.service (5) dokumentiert .

intelfx
quelle
Der von Ihnen angegebene Befehl hat einwandfrei funktioniert und in der Tat die Abhängigkeit von basic.target festgestellt. Es ist eine Schande, dass das Toolset für systemctl so fehlt, aber na ja, es ist ein neues Projekt
Galets
2
@galets: Nach meiner Erfahrung gibt es nur sehr wenige Beispiele für einen solchen Mangel ... Vielleicht werde ich eines Tages die zunehmende Ausführlichkeit des Zyklusreporters umgehen und dem Protokoll einige nützliche Informationen hinzufügen. In der Zwischenzeit können Sie systemd-analyze verify UNITdie Richtigkeit des Geräts überprüfen. Hinter den Kulissen erstellt dieser Befehl eine Instanz des virtuellen Systems und versucht, die angegebene UNIT als erste Transaktion zu laden (als ob dies der Fall wäre default.target). Dadurch werden keine neuen Informationen angezeigt (im Vergleich zu Protokollen), aber Sie müssen zumindest nicht mit aktiviertem Gerät neu starten, um festzustellen, ob es fehlschlägt.
Intelfx
systemd request for enhancement (RFE):
verbosity
20

Sie können den Zyklus mit den Befehlen visualisieren systemd-analyze verify, systemd-analyze dotund das GraphViz dot - Tool:

systemd-analyze verify default.target |&
perl -lne 'print $1 if m{Found.*?on\s+([^/]+)}' |
xargs --no-run-if-empty systemd-analyze dot |
dot -Tsvg >cycle.svg

Sie sollten so etwas sehen:

Bildbeschreibung hier eingeben

Hier können Sie den Zyklus sehen: c.service->b.service->a.service->c.service

Color legend: 
    black     = Requires
    dark blue = Requisite
    dark grey = Wants
    red       = Conflicts
    green     = After

Links:

Evgeny Vereshchagin
quelle
systemd-analyze verifyexistiert hier nicht auf einer debian 8 install.
So
@sjas, systemd-analyze verify verfügbar seit v216. versuchen Sie es systemd-verify. Existiert es?
Evgeny Vereshchagin
hm, es existiert nicht auf Jessie: anonscm.debian.org/cgit/pkg-systemd/systemd.git/tree/debian/…
Evgeny Vereshchagin
1
systemd-analyze verify default.targetallein macht einen anständigen Job in der Darstellung der Schleife ...
Gert van den Berg
0

Schritt 1: Führen Sie den Überprüfungsbefehl für default.target aus

systemd-analyze verify default.target

Schritt 2: Beobachten Sie, welcher Dienst oder welches Ziel in der Meldung "Systemd Brechen des Bestellzyklus durch Löschen eines Auftrags" erwähnt ist, und zeigen Sie die vollständige Abhängigkeitsliste an

systemctl show -p Requires,Wants,Requisite,BindsTo,PartOf,Before,After <service or target name mentioned in the "breaking cycle" message>

Schritt 3: Sehen Sie sich die "after" - und "before" -Gruppen in der normalerweise in definierten Dienst- oder Zieldatei an

/lib/systemd/system

und finden Sie die Dienste oder Ziele, von denen bekannt ist, dass sie sequentiell sind, jedoch in ausgehender Reihenfolge für diesen.

Beispiel:

dbus.service

ist in der Regel Markt "nach"

multi-user.target

aber "vor"

sockets.target

Eine solche Abhängigkeit kann leicht durch einen Anruf beobachtet werden

systemctl list-dependencies default.target

allerdings wenn die datei

/lib/systemd/system/dbus.service

enthält Zeilen wie:

Before=multi-user.target

oder

After=sockets.target

oder beides gleichzeitig bedeutet, dass dbus.service als ausgehend definiert ist und einen endlosen Systemzyklus verursacht.

Die Heilung ist einfach - ändern Sie das Wort "Nach" in "Vorher" und umgekehrt, falls erforderlich.

Oleg Kokorin
quelle