Меня попросили создать systemd
скрипт для новой услуги, foo_daemon
, который иногда попадает в "плохое состояние" и не умирает через SIGTERM
(вероятно, из-за специального обработчика сигналов). Это проблематично для разработчиков, так как им дано указание запускать / останавливать / перезапускать службу через:
systemctl start foo_daemon.service
systemctl stop foo_daemon.service
systemctl restart foo_daemon.service
Иногда из-за foo_daemon
попадая в плохое состояние, мы должны принудительно убить его через:
systemctl kill -s KILL foo_daemon.service
Как я могу настроить свой systemd
сценарий для foo_daemon
так что всякий раз, когда пользователь пытается остановить / перезапустить службу, systemd
воля:
foo_daemon
через SIGTERM
.foo_daemon
завершить.foo_daemon
через SIGKILL
если процесс еще жив (поэтому у нас нет риска перезапуска PID и systemd
вопросы SIGKILL
против неправильного PID). Устройство, которое мы тестируем, быстро порождает / разветвляет множество процессов, поэтому существует редкая, но очень реальная проблема, связанная с переработкой ФИД.SIGKILL
против PID процесса, не беспокоясь об уничтожении переработанного PID.systemd уже поддерживает это из коробки, и это включен по умолчанию.
Единственное, что вы, возможно, захотите настроить, - это тайм-аут, который вы можете сделать с TimeoutStopSec=
. Например:
[Service]
TimeoutStopSec=2
Теперь systemd отправит SIGTERM, подождет две секунды, пока служба завершится, а если этого не произойдет, она отправит SIGKILL.
Если ваша служба не поддерживает систему, вам может потребоваться указать путь к ее файлу PID с помощью PIDFile=
.
Наконец, вы упомянули, что ваш демон порождает множество процессов. В этом случае вы можете установить KillMode=control-group
а systemd будет отправлять сигналы всем процессам в cgroup.
Поскольку никто не упомянул о необходимости Type=oneshot
, вот полный пример, который завершается из-за сбоя тайм-аута.
[Unit]
Description=timeout test
[Service]
Type=oneshot
TimeoutStartSec=2
ExecStart=/bin/sleep 10