Systemd e processo de desova

12

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:

  • Systemd gera /Server.py
  • O Server.py se bifurca e grava o arquivo pid para Systemd
  • Server.py, em seguida, gera processos do servidor na tela do gnu com base em suas instruções
  • O Server.py continua a executar para executar qualquer reinicialização solicitada do servidor

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.

    
por Bottswana 21.05.2015 / 22:11

2 respostas

7

Consegui consertar isso simplesmente definindo KillMode para processar em vez de control-group (padrão). Obrigado a todos

    
por 04.06.2015 / 17:36
4

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.

    
por 22.05.2015 / 00:29