Как написать runit скрипт пользовательской остановки
Я хочу иметь собственный скрипт "stop" runit
(runsv
) выполнять при необходимости остановить / перезапустить процесс. В настоящее время он просто убивает процесс, а затем запускает скрипт "finish". Но в моем случае мой процесс порождает динамически дочерние процессы, поэтому вместо простого kill
, Мне нужно "killtree"
чтобы избавиться от них. Как я могу это сделать?
Я знаю, что это должно быть сделано через control
опции runit, но после прочтения документации мне не совсем понятно, как должен называться скрипт остановки:(
3 ответа
Из документов
Для каждого управляющего символа c, отправляемого в канал управления, runv сначала проверяет, существует ли service / control / c и является ли он исполняемым. Если это так, он запускает service / control / c и ожидает его завершения, прежде чем интерпретировать команду. Если программа завершает работу с кодом возврата 0, RunS воздерживается от отправки службе соответствующего сигнала. Команда o всегда рассматривается как команда u. По команде d сначала проверяется service / control / t, а затем service / control / d. По команде x сначала проверяется service / control / t, а затем service/control/x. Управление дополнительной службой журнала не может быть настроено.
Это означает, что вам нужно создать service_name/control/X
X - исполняемый файл, который будет запускаться при отправке соответствующего sv
команда к службе, как d
команда (вниз). Если ваш скрипт завершает работу со статусом 0, он не будет пытаться отключить сам сервис.
В основном вам нужен исполняемый скрипт на /etc/sv/<service>/control/d
который будет делать что угодно и убивать сервис, убирать пиды и тд
Я должен был решить эту проблему самостоятельно для докера. У меня был запущен сервер uwsgi, и докер (TERM вместо INT) отправил ему неправильный сигнал при остановке контейнера.
Идея файлов control/x состоит в том, чтобы реагировать на полученный сигнал. В моем случае я бы поместил t
файл для сигнала завершения в управление, так как это файл, зарезервированный для термина сигнал. Скрипт должен быть исполняемым.
#!/bin/bash
kill -INT `cat /tmp/project-master.pid`
Сценарий отправляет сигнал int процессу uwsgi, чего я и хочу.
Если управляющий скрипт завершает работу без ошибки (код возврата 0), исходный сигнал не будет отправлен процессу.
Так что в моем случае я смог получить термин "сигнал" и вместо этого послать сигнал "int" процессу обслуживания.
Простой ответ - назвать скрипт очистки "service / finish". Этот скрипт выполняется при выходе из "service / run".
Существует также интерфейс "service/control/ctrl_char". Он позволяет вам выполнять различные действия в зависимости от того, какую команду вы отправляете на runv.