Systemd и процесс нереста

Обычно не отправляйте сюда, но я разорву свои волосы поверх этого. У меня есть сценарий Python, который вилки, когда он запускается, и отвечает за запуск множества других процессов. Этот сценарий запускался при запуске через sysvinit, но недавно я обновился до Debian Jessie, поэтому адаптировал его для запуска через systemd.

К сожалению, я столкнулся с проблемой, которую я не могу решить. Когда вы запускаете скрипт непосредственно в оболочке пользователя, он корректно запускает дочерние процессы, и когда сценарий выходит из дочерних процессов, они становятся сиротами и продолжают работать.

При запуске через systemd, если родительский процесс завершается, все дети тоже выходят (ну, экран, который они запускают в уме и появляется как Dead ???)

В идеале мне нужно перезапустить родительский скрипт, не убивая все дочерние процессы, есть ли что-то, что мне не хватает?

Благодаря!

[Unit] Description=Server commander After=network.target [Service] User=serveruser Type=forking PIDFile=/var/Server/Server.pid ExecStart=/var/Server/Server.py ExecStop=/bin/kill -s TERM $MAINPID [Install] WantedBy=multi-user.target 

Edit: Вероятно, для меня важно отметить, что скрипт Python по сути является «контроллером» для его дочерних процессов. Он запускает и останавливает серверы на экранах gnu по запросу центрального сервера. Обычно он работает, он не запускает службы и не выходит. Однако есть случаи, когда я хотел бы перезагрузить сценарий, не убивая дочерние процессы, даже если это означает, что процессы потеряли сидение до pid 1. На самом деле, даже не важно, запускался ли сценарий Python с процессов, как родительский процесс, если это возможно.

Лучшее объяснение того, как это работает:

  • Systemd spawns /Server.py
  • Server.py создает и записывает файл pid для Systemd
  • Server.py затем запускает серверные процессы на экране gnu в соответствии с его инструкциями
  • Server.py продолжает выполняться для выполнения любых перезапусков, запрошенных с сервера

При запуске без Systemd Server.py можно перезапустить, а экраны gnu, которые запускаются, не затрагиваются. При запуске с помощью Systemd, когда Server.py завершает работу, вместо того, чтобы те процессы, которые были отключены до pid 1, были убиты.

Мне удалось исправить это просто, установив KillMode для обработки вместо контрольной группы (по умолчанию). Спасибо всем

У меня есть сценарий Python, который вилки, когда он запускается, и отвечает за запуск множества других процессов.

Это означает, что вы делаете это неправильно. Еще в этом мгновение.

когда скрипт выходит из дочерних процессов, осиротевшие и продолжают работать.

Это неправильное поведение dæmon. Если «основной» процесс – в этом случае ребенок, который вы разветвили, так как вы указали Type=forking – выходы, systemd считает, что служба деактивирована и завершает любые другие все еще запущенные процессы (в контрольной группе), чтобы прибраться.

Иногда преобразование из скриптов System 5 rc в systemd не является простым, потому что правильный способ делать вещи в systemd совершенно другой. Правильный способ сделать (скажем) OpenVPN, или OpenStack, или OSSEC HIDS в systemd – это не то же самое, что и с rc скриптом. Тот факт, что у вас есть скрипт, который разворачивается, затем порождает целую нагрузку процессов внуков, а затем выходит из ossec-control что эти внуки продолжают работать, указывает на то, что вы совершаете такой же ужас, как и ossec-control , хотя и с двумя меньшими уровнями разветвления , Если вы обнаружите, что пишете «главный» скрипт, который проверяет флаги «включить» и запускает дочерние процессы для «разрешенных» частей вашей системы, вы делаете ту же ошибку, что и ужасный ossec-control .

Никаких таких домашних механизмов не требуется с системой. Это уже сервис-менеджер. По https://unix.stackexchange.com/a/200365/5132 , правильный способ сделать это в systemd – это не иметь одну услугу, которая порождает какую-то дурацкую и запутанную попытку иметь «под-сервисы». Это значит, что каждый дочерний процесс является полноценной службой systemd в своем собственном праве. Затем один включает и отключает и запускает и останавливает различные части системы, используя обычные элементы управления systemd. Как вы можете видеть в случае OSSEC HIDS, простой сервисный модуль шаблона охватывает почти все (одно исключение – в https://askubuntu.com/a/624871/43344 ), что позволяет делать такие вещи, как systemctl enable ossec@agentlessd.service чтобы включить дополнительную службу agentlessd , без какой-либо необходимости для ужасающего механизма «мастер-скрипта», который необходим для системы 5 rc .

Существует множество случаев, не столь экстремальных, как OSSEC HIDS, где такое переосмысление необходимо. Такие MTS, как exim и sendmail, являются двумя такими. Возможно, у вас был единственный сценарий rc который запускает очередь очереди, SMTP Submission dæmon и SMTP Relay dæmon, с кучей переменных ad hoc в файле конфигурации, чтобы точно контролировать, какие из них выполняются. Но правильный способ сделать это с помощью systemd состоит в том, чтобы иметь три соответствующих единицы обслуживания (два из которых имеют связанные сокетные блоки ) и никаких специальных материалов вообще, а также обычные механизмы менеджера сервиса.