У меня есть демон старой школы, которым я хочу управлять с помощью 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. Поэтому я не могу сказать вам, почему это не так распространить эту философию на перезагрузку. Может быть, кто-то из авторов может вмешаться здесь.)