Назад | Перейти на главную страницу

Как настроить systemd для уничтожения и перезапуска демона при перезагрузке?

У меня есть демон старой школы, которым я хочу управлять с помощью systemd. Когда его файл конфигурации изменяется, его нужно убить и перезапустить. Другими словами, после редактирования файла конфигурации, systemctl reload MYSERVICE должен убить процесс и перезапустить его.

Попытка 1: попробуйте значения по умолчанию. Это говорит systemd, как запустить демон, но не как его перезагрузить.

[Service]
ExecStart=/usr/bin/MYSERVICE
Type=simple

В следствии, start и restart работа, но reload дает эту ошибку:

# systemctl reload MYSERVICE
Failed to reload MYSERVICE.service: Job type reload is not applicable for unit MYSERVICE.service.

Попытка 2: Подскажите, как убить процесс. Это убивает процесс, но systemd не перезапускает его за меня.

[Service]
ExecStart=/usr/bin/MYSERVICE
Type=simple
ExecReload=/bin/kill -HUP $MAINPID

...с последующим...

# systemctl daemon-reload
# systemctl reload MYSERVICE

... убивает процесс, но не перезапускается автоматически.

Попытка 3: используйте ExecReload, чтобы перезапустить процесс. Это не удается по нескольким причинам:

ExecReload=/bin/kill -HUP $MAINPID ; /usr/bin/MYSERVICE

... я получаю сообщение об ошибке ...:

# systemctl daemon-reload
# systemctl reload MYSERVICE
Job for MYSERVICE.service failed because the control process exited with error code. See "systemctl status MYSERVICE.service" and "journalctl -xe" for details.

Я ожидал, что будет ReloadType = kill_and_restart или что-то в этом роде, но не повезло.

Как сказать systemd убить и перезапустить демон при перезагрузке?

Ответ - «нет»! Но у нас есть хорошие новости.

Философия systemd заключается в том, что перезагрузка необязательна и ее следует оставить неопределенной, если истинная функция перезагрузки отсутствует. Я бы определил «истинную функциональность перезагрузки» как перезагрузку, которая не уничтожает и не перезапускает службу или не заставляет службу изменять свой PID. Другими словами, systemd хочет только отразить, какие функции существуют.

Вместо этого вы должны использовать systemctl reload-or-restart который выполнит перезагрузку, если она существует, и перезапуск, если ее нет.

На странице руководства ...

   reload-or-restart PATTERN...
       Reload one or more units if they support it. If not, restart them
       instead. If the units are not running yet, they will be started.

   reload-or-try-restart PATTERN...
       Reload one or more units if they support it. If not, restart them
       instead. This does nothing if the units are not running. Note that,
       for compatibility with SysV init scripts, force-reload is
       equivalent to this command.

Следовательно: (1) оставьте поле ExecReload пустым, (2) используйте systemctl reload-or-restart MYSERVICE и (3) все должно быть готово.

Если вы попытаетесь использовать ExecReload для определения способа уничтожения и перезапуска службы, у нее будет новый PID, и systemd будет сбит с толку.

Философия systemd заключается в том, что reload является необязательным, и пользователь systemd должен знать для каждой службы, должен ли он вызывать reload или подделать, позвонив restart.

Поэтому ответ на ваш вопрос: «Это не работает и не должно. Решите эту проблему на следующем более высоком уровне».

Другими словами, systemd хочет, чтобы вы реализовали только "перезагрузить"если базовая служба поддерживает настоящую функцию перезагрузки ... то есть перезагрузку, которая не уничтожает и не перезапускает службу или не заставляет службу изменять свой PID. Другими словами, systemd хочет только отразить, какие функции существуют.

Вы можете спросить себя: а не было бы проще, если бы я мог реализовать «фальшивую» перезагрузку, разрешив ExecReload убить и перезапустить службу? Тогда я мог бы использовать systemctl reload FOO для всех моих сервисов, и мне бы не пришлось вспоминать, какие из них поддерживают его, а какие нет?

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

Например, марионетка предполагает, что служба, управляемая systemd, не имеет reload и по умолчанию убивает и перезапускает процесс. Если тип Service [] добавил способ указать, что перезагрузка существует и что ее следует использовать при уведомлении, ему необходимо будет узнать, какие службы имеют или не имеют встроенной перезагрузки. Chef и все другие системы также должны будут изучить то же самое, потому что systemd хочет, чтобы это было решено на этом уровне. (MiniRant: для запуска процесса systemd кажется всезнающей, всесторонне монтируемой, полностью настраиваемой в пространстве имен системой i-do-all-at-my-layer. Поэтому я не могу сказать вам, почему это не так распространить эту философию на перезагрузку. Может быть, кто-то из авторов может вмешаться здесь.)