Normalmente não poste aqui, mas estou arrancando meu cabelo com este. Eu tenho um script Python que bifurca quando é iniciado e é responsável por iniciar vários outros processos. Esse script costumava ser iniciado na inicialização via sysvinit, mas recentemente eu atualizei para o Debian Jessie, então o adaptei para iniciar via systemd.
Infelizmente, estou com um problema que não consigo resolver. Quando você inicia o script diretamente no shell do usuário, ele inicia os processos filhos corretamente e, quando o script sai, os processos filhos ficam órfãos e continuam em execução.
Quando lançados pelo systemd, se o processo pai sair, todos os filhos também sairão (bem, as telas que eles lançam morrem e aparecem como mortas ???)
Idealmente, preciso poder reiniciar o script pai sem matar todos os processos filhos. Existe algo que estou faltando?
Obrigado!
[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: Provavelmente é relevante para mim salientar que o script Python é essencialmente um 'controlador' para seus processos filhos. Ele inicia e para servidores em telas gnu, conforme solicitado de um servidor central. Normalmente está sempre em execução, não gera serviços e sai. No entanto, há casos em que eu gostaria de poder recarregar o script sem matar processos filhos, mesmo que isso signifique que os processos fiquem órfãos até o pid 1. Na verdade, não importaria se o script Python iniciasse os processos como um processo pai, se isso for possível.
Uma explicação melhor de como funciona:
- Systemd gera /Server.py
- Server.py bifurca e grava o arquivo pid para Systemd
- O Server.py gera processos do servidor na tela gnu com base em suas instruções
- Server.py continua em execução para executar qualquer reinicialização solicitada do servidor
Ao iniciar sem o Systemd, o Server.py pode ser reiniciado e as telas gnu iniciadas não são afetadas. Ao iniciar com o Systemd, quando o Server.py é encerrado, em vez de os processos de tela ficarem órfãos para o pid 1, eles são mortos.
fonte
Server.py
código e uma descrição de como os serviços lançados bifurcam (se bifurcam). No entanto, de um modo geral, esse é um problema de incompatibilidade do protocolo de prontidão .ExecStop=
não é necessário. A ação padrão do systemd ao parar é matar processos. Você pode dar uma olhada na documentação daKillMode=
diretiva.simple
ouforking
, na verdade), o último recurso seriaType=oneshot
,RemainAfterExit=yes
eKillMode=control-group
.Respostas:
Eu consegui consertar isso simplesmente configurando o KillMode para processar em vez do grupo de controle (padrão). Obrigado a todos
fonte
O que indica que você está fazendo errado. Mais nisso daqui a pouco.
Este não é o comportamento correto daemon. Se o processo "principal" - nesse caso, o filho que você bifurcou, desde que você especificou
Type=forking
- sair, o systemd considera o serviço desativado e encerra outros processos ainda em execução (no grupo de controle) para arrumar .Às vezes, a conversão dos
rc
scripts do sistema 5 para o systemd não é direta, porque a maneira correta de fazer as coisas no systemd é bem diferente. A maneira correta de fazer (digamos) OpenVPN, OpenStack ou OSSEC HIDS no systemd não é a mesma que se faria com umrc
script. O fato de você ter um script que está bifurcando, gerando uma carga inteira de processos de netos e saindo esperando que esses netos continuem funcionando indica que você está cometendo o mesmo tipo de horror queossec-control
, embora com dois níveis menores de bifurcação. Se você se encontra escrevendo um script "mestre" que verifica os sinalizadores "ativar" e executa processos filhos para as partes "ativadas" do seu sistema, estará cometendo o mesmo erro que o horrendoossec-control
.Não existem mecanismos caseiros com o systemd. Ele já é um gerente de serviço. Por /unix//a/200365/5132 , o caminho certo para fazer isso no systemd não é ter um serviço que gera alguma tentativa maluca e confusa de ter "sub-serviços". É ter cada processo filho como um serviço de sistema completo por direito próprio. Então, habilita-se e desabilita-se e inicia-se e para-as várias partes do sistema, usando os controles normais do sistema. Como você pode ver no caso OSSEC HIDS, uma unidade de serviço de modelo simples cobre quase todos os serviços (uma exceção está em /ubuntu//a/624871/43344 ), permitindo que você faça coisas como
systemctl enable [email protected]
ativar um opcionalagentlessd
serviço, sem nenhuma necessidade do horrendo mecanismo de "script mestre" necessário ao Sistema 5rc
.Existem muitos casos, talvez não tão extremos quanto o OSSEC HIDS, em que é necessário repensar. MTSes como exim e sendmail são dois. Pode-se ter um único
rc
script que gera um corredor de fila, um daemon SMTP Submission e um daemon SMTP Relay, com várias variáveis de shell ad hoc em um arquivo de configuração para controlar exatamente quais são executadas. Mas a maneira correta de fazer isso com o systemd é ter três unidades de serviço apropriadas (duas das quais têm unidades de soquete associadas ) e nenhum material ad hoc, apenas os mecanismos regulares do gerenciador de serviços.fonte
Você pode simplesmente dormir com o pai e esperar que o systemd o mate no momento da parada.
fonte