metodologia generica per il debug dei cicli di ordinazione in systemd


23

Sono consapevole di seguire il thread e presumibilmente una risposta ad esso . Tranne una risposta non è una risposta in senso generico. Indica quale fosse il problema in un caso particolare, ma non in generale.

La mia domanda è: esiste un modo per eseguire il debug dei cicli di ordinazione in modo generico ? Ad esempio: esiste un comando che descriverà il ciclo e che cosa collega un'unità all'altra?

Ad esempio, ho seguito journalctl -b(per favore, ignora la data, il mio sistema non ha RTC con cui sincronizzare l'ora):

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

dove cvol.service (quello che è stato introdotto e che interrompe il ciclo) è:

[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

Secondo journalctl, cvol.service vuole basic.service, tranne che non lo fa, almeno non ovviamente. Esiste un comando che dimostrerebbe da dove deriva questo link? E in generale, esiste un comando che trova i cicli e mostra dove ha origine ciascun collegamento nel ciclo?

Risposte:


20

Esiste un comando che dimostrerebbe da dove deriva questo link?

Il più vicino che puoi fare è systemctl show -p Requires,Wants,Requisite,BindsTo,PartOf,Before,After cvol.service, che mostrerà gli elenchi delle dipendenze (effettivi) risultanti per una data unità.

c'è un comando, che trova i cicli e mostra dove ha origine ciascun collegamento nel ciclo?

Per quanto ne sappia, non esiste tale comando. In realtà systemd non offre nulla di utile nei cicli di ordinamento del debug (sospiro).

Secondo journalctl, cvol.service vuole basic.service, tranne che non lo fa, almeno non ovviamente.

In primo luogo, le dipendenze requisito ( Wants=, Requires=, BindsTo=etc.) sono indipendenti dipendenze ordinamento ( Before=e After=). Quello che vedi qui è un ciclo di dipendenza degli ordini , cioè non ha nulla a che fare con Wants=ecc.

In secondo luogo, esiste una serie di "dipendenze predefinite" create tra unità di determinati tipi. Sono controllati dalla DefaultDependencies=direttiva nella [Unit]sezione (che è abilitata di default ).

In particolare, a meno che questa direttiva non sia esplicitamente disabilitata, qualsiasi .serviceunità di tipo ottiene implicite Requires=basic.targete After=basic.targetdipendenze, che è esattamente ciò che vedi. Questo è documentato in systemd.service (5) .


Il comando che hai citato ha funzionato perfettamente e in effetti ha rivelato la dipendenza da basic.target. È un peccato che il set di strumenti per systemctl sia così carente, ma vabbè, è un nuovo progetto
galets

2
@galets: a giudicare dalla mia esperienza, ci sono pochissimi esempi di tale carenza ... Forse un giorno mi aggirerò aumentando la verbosità del reporter del ciclo, aggiungendo alcune informazioni utili al registro. Nel frattempo, in realtà, è possibile utilizzare systemd-analyze verify UNITper verificare la correttezza dell'unità. Dietro le quinte, questo comando crea un'istanza di systemd virtuale e tenta di caricare l'UNITÀ specificata come transazione iniziale (come se fosse default.target). Questo non rivelerà alcuna nuova informazione (rispetto ai log), ma almeno non dovrai riavviare con l'unità abilitata per vedere se fallisce.
intelfx

richiesta di miglioramento del sistema (RFE): aumentare la verbosità del reporter del ciclo
adrelanos,

20

È possibile visualizzare il ciclo con i comandi systemd-analyze verify, systemd-analyze dote il GraphViz dot strumento:

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

Dovresti vedere qualcosa del genere:

inserisci qui la descrizione dell'immagine

Qui puoi vedere il ciclo: c.service->b.service->a.service->c.service

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

link:


systemd-analyze verifynon esiste qui su un'installazione di debian 8.
sjas,

@sjas, systemd-analyze verify disponibile da allora v216. provare systemd-verify. Esiste?
Evgeny Vereshchagin,


1
systemd-analyze verify default.targetda solo fa un lavoro decente nel mostrare il ciclo ...
Gert van den Berg

0

passaggio 1: eseguire il comando di verifica per default.target

systemd-analyze verify default.target

passaggio 2: osservare quale servizio o destinazione menzionato nel messaggio "systemd Interruzione del ciclo di ordinazione eliminando il lavoro" e visualizzare l'elenco completo delle dipendenze

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

passaggio 3: esaminare i gruppi "after" e "before" all'interno del servizio o del file di destinazione normalmente definiti in

/lib/systemd/system

e trova i servizi o gli obiettivi ben noti per essere sequenziali ma sono in ordine di uscita per questo.

esempio:

dbus.service

è di solito il mercato "dopo"

multi-user.target

ma "prima"

sockets.target

tale dipendenza potrebbe essere facilmente osservata chiamando

systemctl list-dependencies default.target

tuttavia se il file

/lib/systemd/system/dbus.service

contiene linee come:

Before=multi-user.target

o

After=sockets.target

o entrambi contemporaneamente, significa che dbus.service è definito in uscita e sta causando un ciclo infinito di sistema.

la cura è semplice - cambia la parola "Dopo" in "Prima" e viceversa, se necessario.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.