В systemd, в чем разница между After = и require =?


55

Я создаю файл systemd .service, и мне нужна помощь, чтобы понять разницу между Requires=и After=. Страница man говорит, что Requires=«Настраивает зависимости требований от других модулей». и After=«Конфигурирует зависимости порядка между блоками». Какая разница?

Ответы:


45

After=настраивает порядок обслуживания (делайте X только после Y), при этом Requires=зависимости состояния. Если вы не укажете заказ, служба, зависящая от другого, будет запущена одновременно с той, от которой она зависит. Кроме того, как я понимаю (хотя я не могу проверить это сейчас и не могу найти ссылку), After=это «слабая связь», и служба с таким оператором все равно будет работать, если имя, указанное в After=строке isn не началось вообще, хотя Require=могло бы предотвратить его запуск, если требование не выполнено.

Ссылаясь на https://www.freedesktop.org/software/systemd/man/systemd.unit.html :

Требуется =

Настраивает зависимости требований от других модулей. Если это устройство активируется, перечисленные здесь устройства также будут активированы. Если один из других модулей будет деактивирован или его активация не удастся, этот блок будет деактивирован. Эта опция может быть указана более одного раза, или несколько единиц, разделенных пробелами, могут быть указаны в одной опции, и в этом случае будут созданы зависимости требований для всех перечисленных имен. Обратите внимание, что зависимости требований не влияют на порядок запуска или остановки служб. Это должно быть настроено независимо с параметрами After = или Before =. Если для модуля foo.service требуется модуль bar.service, настроенный с помощью Требуется =, и не задан порядок упорядочения с помощью After = или До =, тогда оба модуля будут запущены одновременно и без каких-либо задержек между ними, если активирован foo.service. Часто,

а также

До =, После =

Разделенный пробелами список имен устройств. Настраивает порядок упорядочения зависимостей между блоками. Если модуль foo.service содержит параметр Before = bar.service, и оба модуля запускаются, запуск bar.service откладывается до запуска foo.service. Обратите внимание, что этот параметр не зависит и не ортогонален зависимостям требований, как сконфигурировано с помощью require =. Распространенным шаблоном является включение имени устройства в опции «После =» и «Требуется =», и в этом случае перечисленные модули будут запущены до того, как будет настроен модуль с этими параметрами. Эта опция может быть указана более одного раза, и в этом случае создаются упорядочивающие зависимости для всех перечисленных имен. After = - это обратное значение до =, т. Е. В то время как After = гарантирует, что сконфигурированный модуль запускается после завершения запуска перечисленного модуля, Before = обеспечивает обратное, т. Е. что сконфигурированный модуль полностью запущен до запуска указанного модуля. Обратите внимание, что, когда два блока с упорядоченной зависимостью между ними отключены, применяется обратный порядок запуска. т. е. если блок настроен с After = на другом блоке, первый останавливается до последнего, если оба выключены. При наличии двух блоков с любой зависимостью упорядочения между ними, если один блок выключен, а другой запущен, отключение заказывается перед запуском. Не имеет значения, является ли зависимость упорядочения After = или Before =. Также не имеет значения, какой из двух выключен, если один выключен, а другой запущен. Выключение заказывается перед запуском во всех случаях. Если между двумя модулями нет упорядочивающих зависимостей, они выключаются или запускаются одновременно,


7
Что такое зависимость, если не утверждение порядка? (серьезно ... я не понимаю разницы)
TomOnTime

Смотрите мое редактирование. Мое понимание: After=Xозначало бы «Делать это после X, если X готово», а Require=Xозначало бы: «Не делайте этого вообще, если вы не можете сделать X».
Свен

Before=Часть страницы человека , кажется, подтверждает это. If a unit foo.service contains a setting Before=bar.service and both units are being started, bar.service's start-up is delayed until foo.service is started up Насколько я понимаю, порядок не будет исполняться, если bar.serviceон все равно не будет запущен и foo.serviceначнется нормально.
Свен

10

Одним из основных отличий является то,

  • After только проверяет, активирован ли уже блок, и не активирует явно указанные блоки.
  • Единицы, перечисленные в Requires, активируются вместе с единицей. Если какой-либо из требуемых блоков не запускается, блок не активируется.

Считайте, что у меня есть файл модуля test-app.service,

[Unit]
Description=test app
After=network-online.target

Вот что произойдет, когда этот оператор будет выполнен,

  • Afterпроверяет, если network-online.target.
  • если network-online.targetне начался, он будет ждать.
  • test-appначинается только после того, network-online.targetкак активен

Если бы я имел Requiresвместо этого,

[Unit]
Description=test app
Requires=network-online.target

Вот что произойдет, когда этот оператор будет выполнен,

  • network-online.targetи test-appактивируются вместе
  • Если network-online.targetне удается запустить test-appне будет активирован.

2

systemd - менеджер по работе. Страница руководства не очень точна относительно того, как все работает.

При загрузке systemd создает транзакцию, состоящую из заданий для задания привязки (т. Е. Запускает задание для default.target). Все эти зависимости и отношения определяют, как и какие задания будут запускаться. Порядок определяет, какую работу (-и) будет ждать каждая другая работа. Таким образом, модуль default.target находится в центре всего этого, поэтому при включении модулей вы используете обратную зависимость, которая через включение systemctl создает символическую ссылку файловой системы, обозначающую прямую зависимость, за которой может следовать systemd (также зачем вам нужны символические ссылки файловой системы в первое место). Аналогично, когда вы вручную запускаете какой-то модуль, тогда этот модуль является якорем, и транзакция вычисляется по нему.

Не вдаваясь в подробности, я объясню, что делает «требует» и «после».

Требуется = заставит systemd запускать стартовое задание для требуемого модуля, когда вы запускаете стартовое задание (явно или через зависимость: внутри нет различий). У него также есть свойство инициировать остановку на вас, когда это устройство остановлено (примечание: остановлено, не останавливается само по себе) или перезапущено. Это означает, что если какая-то зависимость / systemctl вызывает его остановку / перезапуск, вы также остановите / перезапустите. Однако, если это произойдет само по себе, вы не остановитесь, поскольку не было работы, и изменение состояния произошло без участия systemd. Вот где вы должны использовать BindsTo = (аналогично устройствам, которые по понятным причинам могут перейти в неактивное состояние без участия systemd).

Теперь использование After = рекомендуется, так как «Требуется = один» очень важно для того, что он делает: отмените заявку, если не удалось запустить задание. Эта отмена, однако, работает только с заданиями, т. Е. Если другой модуль не определяет порядок, systemd запускает оба параллельно, и если его начальное задание заканчивается до сбоя вашего начального задания, оно не будет отменено (на самом деле его нельзя отменить) , Использование After = означает, что другое задание продолжает ожидать до тех пор, пока не завершится начальное задание требуемого модуля, и в зависимости от результата, если оно не удалось, задание запуска вашего устройства отменяется с результатом задания JOB_DEPENDENCY (почему вы используете желтый [DEPEND] при загрузке для таких случаев). Следовательно, этот эффект аннулирования является недетерминированным без использования After =.

Вот почему использование Wants = без After = хорошо, если вы не хотите ждать запуска другого модуля: поскольку там нет аннулирования, поэтому нет гонки. В этом случае это не более чем механизм синхронизации.

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.