ogólna metodologia debugowania cykli zamawiania w systemie

23

Jestem świadomy podążania za wątkiem i rzekomo odpowiedzi na to . Tyle że odpowiedź nie jest odpowiedzią w sensie ogólnym. Mówi o tym, jaki był problem w jednym konkretnym przypadku, ale nie ogólnie.

Moje pytanie brzmi: czy istnieje sposób na ogólne debugowanie cykli zamawiania ? Np .: czy istnieje polecenie opisujące cykl i łączące jedną jednostkę z drugą?

Na przykład mam następujące journalctl -b(proszę zignorować datę, mój system nie ma RTC do synchronizacji czasu):

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

gdzie cvol.service (ten, który został wprowadzony i który przerywa cykl) to:

[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

Według Journalctl, cvol.service chce basic.service, poza tym, że nie, przynajmniej nie w sposób oczywisty. Czy istnieje polecenie, które pokazuje, skąd pochodzi ten link? Ogólnie rzecz biorąc, czy istnieje polecenie, które odnajdzie cykle i pokaże, skąd pochodzi każde łącze w cyklu?

galety
źródło

Odpowiedzi:

20

Czy istnieje polecenie, które pokazuje, skąd pochodzi ten link?

Najbliższe, co możesz zrobić systemctl show -p Requires,Wants,Requisite,BindsTo,PartOf,Before,After cvol.service, to pokazać wynikowe (skuteczne) listy zależności dla danej jednostki.

czy istnieje polecenie, które odnajdzie cykle i pokaże, skąd pochodzi każde łącze w cyklu?

Według mojej wiedzy nie ma takiego polecenia. Właściwie systemd nie oferuje niczego, co mogłoby pomóc w debugowaniu cykli zamawiania (westchnienie).

Według Journalctl, cvol.service chce basic.service, poza tym, że nie, przynajmniej nie w sposób oczywisty.

Po pierwsze, Zależności wymogu ( Wants=, Requires=, BindsTo=etc.) są niezależne od uzależnień Zamawianie ( Before=a After=). To, co tu widzisz, to cykl zależności porządku , tzn. Nie ma on nic wspólnego z Wants=itp.

Po drugie, istnieje szereg „domyślnych zależności” utworzonych między jednostkami niektórych typów. Są one kontrolowane przez DefaultDependencies=dyrektywę w [Unit]sekcji (która jest domyślnie włączona ).

W szczególności, chyba że ta dyrektywa zostanie wyraźnie wyłączona, jakakolwiek .servicejednostka typu zostanie domyślna Requires=basic.targeti będzie After=basic.targetzależała, co dokładnie widać. Jest to udokumentowane w systemd.service (5) .

intelfx
źródło
Komenda, którą zacytowałeś, działała idealnie i rzeczywiście ujawniła zależność od basic.target. Szkoda, że ​​brakuje zestawu narzędzi dla systemctl, ale cóż, to nowy projekt
galets
2
@ galets: Sądząc z mojego doświadczenia, istnieje bardzo niewiele przykładów takiego niedoboru ... Może pewnego dnia obejdę zwiększanie gadatliwości reportera cyklu, dodając przydatne informacje do dziennika. Tymczasem możesz użyć systemd-analyze verify UNITdo sprawdzenia poprawności urządzenia. Za kulisami to polecenie tworzy wirtualną instancję systemd i próbuje załadować podaną JEDNOSTKĘ jako transakcję początkową (jakby była default.target). Nie ujawni to żadnych nowych informacji (w porównaniu do dzienników), ale przynajmniej nie będziesz musiał restartować się z włączoną jednostką, aby sprawdzić, czy się nie powiedzie.
intelfx
systemowe zgłoszenie prośby o ulepszenie (RFE): zwiększenie gadatliwości reportera cyklu
adrelanos
20

Można wyobrazić sobie cykl z poleceniami systemd-analyze verify, systemd-analyze dota Graphviz dot narzędzia:

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

Powinieneś zobaczyć coś takiego:

wprowadź opis zdjęcia tutaj

Tutaj możesz zobaczyć cykl: c.service->b.service->a.service->c.service

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

Spinki do mankietów:

Evgeny Vereshchagin
źródło
systemd-analyze verifynie istnieje tutaj w instalacji Debian 8.
sjas,
@sjas, systemd-analyze verify dostępne od v216. spróbuj systemd-verify. Czy to istnieje?
Evgeny Vereshchagin
hm, nie istnieje na Jessie: anonscm.debian.org/cgit/pkg-systemd/systemd.git/tree/debian/…
Evgeny Vereshchagin
1
systemd-analyze verify default.targetsamodzielnie robi porządną robotę, pokazując pętlę ...
Gert van den Berg
0

krok 1: uruchom polecenie weryfikacji dla default.target

systemd-analyze verify default.target

krok 2: obserwuj usługę lub cel wymieniony w komunikacie „systemd Przerwanie cyklu zamawiania przez usunięcie zadania” i wyświetl jego pełną listę zależności

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

krok 3: spójrz na grupy „za” i „przed” w pliku usługi lub pliku docelowym, zwykle zdefiniowanym w

/lib/systemd/system

i znajdź usługi lub cele, o których wiadomo, że są sekwencyjne, ale są w kolejności wychodzącej dla tego.

przykład:

dbus.service

jest zwykle rynkowy „po”

multi-user.target

ale „przed”

sockets.target

taką zależność można łatwo zaobserwować dzwoniąc

systemctl list-dependencies default.target

jednak jeśli plik

/lib/systemd/system/dbus.service

zawierają wiersze takie jak:

Before=multi-user.target

lub

After=sockets.target

lub oba jednocześnie, oznacza, że ​​usługa dbus.service jest zdefiniowana jako wychodząca i powoduje to systemowy niekończący się cykl.

wyleczenie jest prosty - zmiana słowa „po” do „przed” i vice versa, jeśli to konieczne.

Oleg Kokorin
źródło