metodología genérica para depurar ciclos de pedidos en systemd

23

Soy consciente del siguiente hilo y supuestamente una respuesta al mismo . Excepto que una respuesta no es una respuesta en sentido genérico. Indica cuál fue el problema en un caso particular, pero no en general.

Mi pregunta es: ¿hay alguna forma de depurar los ciclos de pedidos de forma genérica ? Por ejemplo: ¿hay un comando que describa el ciclo y qué vincula una unidad con otra?

Por ejemplo, he seguido journalctl -b(ignore la fecha, mi sistema no tiene RTC para sincronizar la hora):

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

donde cvol.service (el que se introdujo y que rompe el ciclo) es:

[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

Según journalctl, cvol.service quiere basic.service, excepto que no lo hace, al menos no obviamente. ¿Hay algún comando que demuestre de dónde se deriva este enlace? Y, en general, ¿hay un comando que encuentre los ciclos y muestre dónde se origina cada enlace del ciclo?

galets
fuente

Respuestas:

20

¿Hay algún comando que demuestre de dónde se deriva este enlace?

Lo más cercano que puede hacer es systemctl show -p Requires,Wants,Requisite,BindsTo,PartOf,Before,After cvol.servicemostrar las listas de dependencias resultantes (efectivas) para una unidad determinada.

¿hay un comando que encuentre los ciclos y muestre dónde se origina cada enlace en el ciclo?

Que yo sepa, no existe tal comando. En realidad, systemd no ofrece nada para ayudar a depurar los ciclos de pedido (suspiro).

Según journalctl, cvol.service quiere basic.service, excepto que no lo hace, al menos no obviamente.

En primer lugar, las dependencias de requisitos ( Wants=, Requires=, BindsTo=etc.) son independientes de las dependencias de pedidos ( Before=y After=). Lo que ves aquí es un ciclo de dependencia de pedidos , es decir, no tiene nada que ver con Wants=etc.

Segundo, hay una serie de "dependencias predeterminadas" creadas entre unidades de ciertos tipos. Están controlados por la DefaultDependencies=directiva en la [Unit]sección (que está habilitada de forma predeterminada ).

En particular, a menos que esta directiva esté deshabilitada explícitamente, cualquier .serviceunidad de tipo se vuelve implícita Requires=basic.targety After=basic.targetdependencias, que es exactamente lo que ve. Esto está documentado en systemd.service (5) .

intelfx
fuente
El comando que citó funcionó perfectamente, y de hecho reveló dependencia en basic.target. Es una pena que el conjunto de herramientas para systemctl sea tan escaso, pero bueno, es un nuevo proyecto
galets el
2
@galets: A juzgar por mi experiencia, hay muy pocos ejemplos de tal escasez ... Tal vez algún día evitaré aumentar la verbosidad del reportero del ciclo, agregando información útil al registro. Mientras tanto, en realidad, puede usar systemd-analyze verify UNITpara verificar la corrección de la unidad. Detrás de escena, este comando crea una instancia virtual del sistema e intenta cargar la UNIDAD dada como la transacción inicial (como si fuera default.target). Esto no revelará ninguna información nueva (en comparación con los registros), pero al menos no tendrá que reiniciar con la unidad habilitada para ver si falla.
intelfx
solicitud de mejora de systemd (RFE): aumentar la verbosidad del reportero de ciclo
adrelanos
20

Puede visualizar el ciclo con los comandos systemd-analyze verify, systemd-analyze doty la GraphViz dot herramienta:

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

Debería ver algo como esto:

ingrese la descripción de la imagen aquí

Aquí puedes ver el ciclo: c.service->b.service->a.service->c.service

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

Campo de golf:

Evgeny Vereshchagin
fuente
systemd-analyze verifyno existe aquí en una instalación de debian 8.
sjas
@sjas, systemd-analyze verify disponible desde v216. tratar systemd-verify. ¿Existe?
Evgeny Vereshchagin
hm, no existe en Jessie: anonscm.debian.org/cgit/pkg-systemd/systemd.git/tree/debian/…
Evgeny Vereshchagin
1
systemd-analyze verify default.targetpor sí solo hace un trabajo decente al mostrar el ciclo ...
Gert van den Berg
0

Paso 1: ejecuta el comando de verificación para default.target

systemd-analyze verify default.target

Paso 2: observe qué servicio o destino se menciona en el mensaje "systemd Romper el ciclo de pedidos eliminando el trabajo" y visualice su lista completa de dependencias

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

Paso 3: mira los grupos "después" y "antes" dentro del servicio o archivo de destino generalmente definido en

/lib/systemd/system

y encuentre que los servicios u objetivos bien conocidos son secuenciales pero están en orden de salida para este.

ejemplo:

dbus.service

es generalmente el mercado "después"

multi-user.target

pero "antes"

sockets.target

dicha dependencia podría observarse fácilmente llamando

systemctl list-dependencies default.target

sin embargo si el archivo

/lib/systemd/system/dbus.service

contener líneas como:

Before=multi-user.target

o

After=sockets.target

o ambos simultáneamente, significa que dbus.service está definido como saliente y está causando un ciclo interminable systemd.

la cura es simple: cambie la palabra "Después" a "Antes" y viceversa si es necesario.

Oleg Kokorin
fuente