Ещё раз: я не защищаю systemd, я критикую sysvinit, причём исключительно по части service supervision, остальное меня совершенно устраивает.
(c) GotF
А теперь, мужики, давайте подумаем. Вводная:
- К init-у репарентятся все процессы с помершим родителем.
- init для всего этого счастья ловит SIGCHLD-ы, когда они дохнут.
- если померший процесс был запущен init-ом из правила inittab, он перезапускается в случае необходимости. В ином случае не происходит ничего.
Что нам мешает добавить гибкости в эту схему? init управляется через /dev/initctl. Мы можем слегка доработать его управление и получить возможность «ставить на контроль» произвольные PID-ы.
Следующая команда будет ставить указанный pid на контроль:
/sbin/telinit --waitpid $pid --run some command
Собственно, всё. Это был механизм.
Теперь use case, для чего нам это нужно. Возьмём обычный rc.d-подобный метод запуска демонов. Напомню вам, что там происходит:
- rc запускает нужный демон.
- демон записывает в /var/run/blabla.pid свой pid.
- пока содержимое /var/run/blabla.pid соответствует живому pid-у, демон считается запущенным.
Итак, вам нужен service supervision. По сути, всё, что вам нужно знать, это когда pid умрёт. Что мы делаем:
- rc запускает демон blabla.
- демон записывает в /var/run/blabla.pid свой pid.
- rc выполняет команду /sbin/telinit --waitpid `cat /var/run/blabla.pid` --run /etc/rc.died blabla
- когда процесс умирает (или если он уже мертв на момент попадания команды в init), init вызывает команду /etc/rc.died blabla. Если демон blabla всё еще нужен (не помечен как выключенный), он перезапускается.
Мысли? Мнения? Критика?