Consegui consertar isso simplesmente definindo KillMode para processar em vez de control-group (padrão). Obrigado a todos
Normalmente não poste aqui, mas estou rasgando meu cabelo por causa disso. Eu tenho um script Python que se bifurca quando é lançado e é responsável por iniciar vários outros processos. Este script costumava ser lançado na inicialização via sysvinit, mas recentemente eu atualizei para o Debian Jessie, então o adaptei para o lançamento via systemd.
Infelizmente, estou me deparando com um problema que não consigo resolver. Quando você inicia o script diretamente em um shell de usuário, ele inicia seus processos filho corretamente e, quando o script sai, os processos filhos ficam órfãos e continuam sendo executados.
Quando iniciado Via systemd, se o processo pai sair, todos os filhos saem também (Bem, os Screen's que eles lançam no dado e aparecem como Dead ???)
O ideal é que eu seja capaz de reiniciar o script pai sem matar todos os processos filhos. Há algo que está 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
Editar: Provavelmente é relevante para mim apontar que o script Python é essencialmente um 'controlador' para seus processos filhos. Ele inicia e pára os servidores nas telas do gnu, conforme solicitado a partir 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 filho, mesmo que isso signifique que os processos estão órfãos de pid 1. De fato, não importaria se o script Python iniciava processos como um processo pai, se isso for possível.
Uma explicação melhor de como funciona:
Ao iniciar sem o Systemd, o Server.py pode ser reiniciado e as telas do gnu lançadas não são afetadas. Ao iniciar com o Systemd, quando o Server.py é desligado, em vez de os processos de tela ficarem órfãos do pid 1, eles são mortos.
I have a Python script that forks when it launches, and is responsible for starting a bunch of other processes.
O que indica que você está fazendo errado. Mais nisso daqui a pouco.
when the script exits the child processes are orphaned and continue to run.
Este não é o comportamento correto do daemon. Se o processo "principal" - neste caso, o filho que você bifurcou, desde que você especificou Type=forking
- exits, o systemd considera que o serviço foi desativado e encerra qualquer outro processo ainda em execução (no grupo de controle), a fim para arrumar.
Às vezes, a conversão do System 5 rc
scripts para o systemd não é direta, porque o jeito certo de fazer as coisas no systemd é bem diferente. O caminho certo para fazer (digamos) OpenVPN, ou OpenStack, ou OSSEC HIDS no systemd não é o mesmo que um faria com um script rc
. O fato de você ter um script que está bifurcando, então gerando uma grande quantidade de processos de netos, e então esperando que os netos continuem correndo indica que você está perpetrando o mesmo tipo de horror que ossec-control
, embora com dois níveis a menos de bifurcação . Se você se encontrar escrevendo um script "mestre" que marque "ativar" sinalizadores e execute processos filhos para as partes "ativadas" de seu sistema, então você está cometendo o mesmo erro que o horrendo ossec-control
.
Nenhum mecanismo caseiro é necessário com o systemd. já é um gerenciador de serviços. Por link , o jeito certo de fazer isso no systemd é não ter um serviço que gera algum maluco e confuso tente ter "sub-serviços". É fazer com que cada criança seja processada como um serviço de sistema completo por direito próprio. Em seguida, um ativa e desativa, e inicia e pára, as várias partes do sistema usando os controles normais do systemd. Como você pode ver no caso OSSEC HIDS, uma unidade de serviço de modelo simples cobre quase todos (uma exceção é em serviços link ) , permitindo que alguém faça coisas como systemctl enable [email protected]
para habilitar um serviço agentlessd
opcional, sem qualquer necessidade do horrendo mecanismo de "script mestre" que era necessário com o System 5 rc
.
Existem muitos casos, talvez não tão extremos como o OSSEC HIDS, em que tal repensar é necessário. MTSes como exim e sendmail são dois desses. Pode-se ter um único script rc
que gera um corredor de fila, um servidor de Submissão SMTP e um servidor de retransmissão SMTP, com um monte de variáveis de shell ad hoc em um arquivo de configuração para controlar exatamente quais são executadas. Mas o jeito certo de fazer isso com o systemd é ter três unidades de serviço adequadas (duas das quais possuem unidades de soquete ) e nenhum material ad hoc, apenas o regular mecanismos do gerenciador de serviços.