общая методология отладки циклов упорядочения в systemd

23

Я в курсе следующей ветки и якобы ответ на нее . За исключением ответа не является ответом в общем смысле. Это говорит о том, что проблема была в одном конкретном случае, но не в целом.

Мой вопрос: есть ли способ отладки циклов заказа в общем виде? Например: есть ли команда, которая будет описывать цикл и что связывает один блок с другим?

Например, у меня есть следующее journalctl -b(пожалуйста, не обращайте внимания на дату, в моей системе нет времени RTC для синхронизации времени):

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

где cvol.service (тот, который был введен, и который нарушает цикл):

[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

Согласно journalctl, cvol.service хочет basic.service, за исключением того, что он этого не делает, по крайней мере, очевидно. Есть ли команда, которая продемонстрировала бы, откуда взята эта ссылка? И вообще, есть ли команда, которая найдет циклы и покажет, где происходит каждая ссылка в цикле?

Galets
источник

Ответы:

20

Есть ли команда, которая продемонстрировала бы, откуда взята эта ссылка?

Самое близкое, что вы можете сделать systemctl show -p Requires,Wants,Requisite,BindsTo,PartOf,Before,After cvol.service, это показать итоговые (эффективные) списки зависимостей для данного модуля.

есть ли команда, которая найдет циклы и покажет, где происходит каждая ссылка в цикле?

Насколько мне известно, такой команды нет. На самом деле systemd не предлагает ничего, чтобы помочь в отладке циклов упорядочения (вздох).

Согласно journalctl, cvol.service хочет basic.service, за исключением того, что он этого не делает, по крайней мере, очевидно.

Во-первых, зависимости требований ( Wants=, Requires=и BindsTo=т. Д.) Не зависят от порядка упорядочения ( Before=и After=). То, что вы видите здесь, это цикл зависимости порядка , то есть он не имеет ничего общего с Wants=т. Д.

Во-вторых, существует ряд «зависимостей по умолчанию», созданных между единицами определенных типов. Они контролируются DefaultDependencies=директивой в [Unit]разделе (которая включена по умолчанию ).

В частности, если эта директива явно не отключена, любой .serviceмодуль -типа получает неявные Requires=basic.targetи After=basic.targetзависимости, что вы и видите. Это задокументировано в systemd.service (5) .

intelfx
источник
Процитированная вами команда отлично сработала и действительно выявила зависимость от basic.target. Жаль, что так мало набора инструментов для systemctl, ну да ладно, это новый проект
galets
2
@galets: Судя по моему опыту, примеров такой нехватки очень мало ... Может быть, когда-нибудь мне удастся обойти подробности репортера цикла, добавив в журнал некоторую полезную информацию. Между тем, на самом деле, вы можете использовать, systemd-analyze verify UNITчтобы проверить правильность устройства. За кулисами эта команда создает виртуальный экземпляр systemd и пытается загрузить данный UNIT в качестве начальной транзакции (как если бы она была default.target). Это не откроет никакой новой информации (по сравнению с журналами), но, по крайней мере, вам не придется перезагружаться с включенным устройством, чтобы увидеть, выйдет ли оно из строя.
intelfx
Системный запрос на усовершенствование (RFE): увеличьте многословие репортера цикла
adrelanos
20

Вы можете представить себе цикл с командами systemd-analyze verify, systemd-analyze dotи GraphViz dot инструмент:

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

Вы должны увидеть что-то вроде этого:

введите описание изображения здесь

Здесь вы можете увидеть цикл: c.service->b.service->a.service->c.service

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

Ссылки:

Евгений Верещагин
источник
systemd-analyze verifyне существует здесь при установке Debian 8
Sjas
@sjas, systemd-analyze verify доступно с тех пор v216. попробуй systemd-verify. Это существует?
Евгений Верещагин
хм, его нет на Джесси: anonscm.debian.org/cgit/pkg-systemd/systemd.git/tree/debian/…
Евгений Верещагин
1
systemd-analyze verify default.targetсам по себе делает достойную работу в показе цикла ...
Герт ван ден Берг
0

Шаг 1: запустить команду проверки для default.target

systemd-analyze verify default.target

Шаг 2: посмотрите, какая служба или цель упоминаются в сообщении «systemd Прерывание цикла упорядочения путем удаления задания», и отобразите полный список зависимостей.

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

Шаг 3: посмотрите на группы «после» и «до» внутри файла службы или целевого файла, обычно определяемого в

/lib/systemd/system

и найдите службы или цели, которые, как известно, являются последовательными, но в исходящем порядке для этой.

пример:

dbus.service

обычно рынок "после"

multi-user.target

но "до"

sockets.target

такую ​​зависимость можно легко увидеть, позвонив

systemctl list-dependencies default.target

Однако если файл

/lib/systemd/system/dbus.service

содержат строки вроде:

Before=multi-user.target

или

After=sockets.target

или оба одновременно означает, что dbus.service определен как исходящий и вызывает бесконечный цикл systemd.

лечение просто - изменить слово «После» к «До» и наоборот , если это необходимо.

Олег Кокорин
источник