O systemd pode manipular daemons de bifurcação dupla?

1

O systemd pode lidar com daemons com garfo duplo?

Eu usei anteriormente init.d / script para gerenciar daemons que escrevi e que funcionaram sem falhas por anos. Agora eu me encontro precisando fornecer um script systemd / e não consigo fazer isso funcionar com o modo como eu faço o código de configuração do daemon.

Quando eu configuro um daemon, bato duas vezes para soltar o terminal de controle e evito ser líder de sessão.

O problema com isto é que eu confirmei que quando você faz isso systemd / perde a faixa e mata o daemon. Eu também confirmei que pular o segundo fork faz com que ele funcione novamente com systemd / .

Meu básico (ligeiramente simplificado para o propósito desta discussão) systemd / script é

[Unit]
Description=GM7 Service Daemon

[Service]
Type=forking
ExecStart=/usr/bin/g7ctrl

[Install]
WantedBy=multi-user.target

Então, eu acho que a minha pergunta é: Eu preciso mudar a maneira como eu fiz o código de configuração do daemon em C / C ++ na última década ou há opções para obter systemd / para rastrear um duplo fork?

Eu ainda não li muito sobre o funcionamento interno se o próprio systemd gerar processos para cada daemon que ele inicia, caso em que meu duplo fork realmente seria obsoleto

Eu admito que a maneira como eu fiz isso (double fork) é parcialmente por razões históricas, mas na época eu fiz uma leitura bastante intensiva sobre as melhores práticas e foi isso que eu então criei ( uma década ou mais atrás)

    
por Johan 19.10.2018 / 19:25

2 respostas

3

Do I need to change the way I have done daemon setup code in C/C++ for the last decade?

Sim.

Mesmo uma década ou mais atrás, este não era o caminho certo a seguir. Não está certo desde o início dos anos 90 com o AIX System Resource Controller. Os usuários do daemontools defenderam não fazer as coisas desta maneira a partir do final dos anos 90 em diante. Não era certo para a Upstart que os principais sistemas operacionais Linux começaram a adotar em 2006. Não era certo para executar as coisas da AT & T System 5 Release 3 inittab no início dos anos 80.

Não é certo para o systemd. Mesmo que as pessoas possam lhe falar sobre o tipo forking , o que elas geralmente esquecem, ou nem sabem, para dizer é que esse é um protocolo de prontidão de serviço específico, que depende de bifurcação dupla sendo feito de uma maneira particular. Pior, a maneira que alguém precisa fazer para falar corretamente o protocolo não combina bem com o modo como você e os outros escreverão seus programas em C / C ++.

Em 2008, minha Resposta com Frequência sobre o assunto já existia por cerca de três quartos de uma década, e eu e outros tínhamos dito às pessoas a mesma coisa por um bom tempo antes de colocá-las na forma da FGA. / p>

A IBM vinha dizendo isso em um redbook desde 1995.

Alguns Johnny-come-latelys têm dito a mesma coisa, do ponto de vista do sistema, no manual do sistema por meros 8 anos ou mais. ☺

Deixe o subsistema de gerenciamento de serviços manipular tudo isso. Seu programa já está sendo executado em um contexto do daemon quando ele começa a ser executado.

Se você realmente quiser manter todo o código que depende da falácia da demonização sendo verdade, então pelo menos faça o que muitas outras pessoas têm feito (em parte em resposta às pessoas daemontools) feito nas últimas duas décadas e dê ao mundo uma opção de linha de comando que desliga tudo . Mas, por favor, não faça com que a opção de linha de comando funcione como uma opção de depuração.

Leitura adicional

por 19.10.2018 / 20:21
1

Sim, o systemd é capaz de lidar com daemons duplos de bifurcação ao usar Type=forking .

Enquanto houver um processo deixado quando o processo principal sair, o systemd assumirá que é o processo principal.

Veja este exemplo sobre serviços tradicionais de bifurcação no systemd documentação para mais detalhes e uma descrição mais detalhada de como Type=forking funciona.

O systemd é mais rigoroso sobre o processo inicial do iniciador e o daemon sendo iniciado e pronto. A partir desse exemplo:

Once it exits successfully and at least a process remains (and RemainAfterExit=no), the service is considered started.

Portanto, é possível que o que está acontecendo no seu caso seja que o processo inicial esteja saindo logo depois de bifurcar o primeiro filho (que então acha que é o processo principal de seu serviço) e então o primeiro filho se bifurca novamente e sai. O systemd acha que o serviço está terminado, quando na verdade não é.

Alguns argumentariam esse comportamento é interrompido mesmo no init do System V :

Again, not synchronizing properly is broken for sysvinit as much as it is broken for systemd. We deal with it to some point, but the only fully safe and correct way to handle this is to fix the programs in question.

De qualquer forma, o melhor conselho que eu tenho para você é pular o duplo bifurcação quando executado no systemd. Você não precisa remover a habilidade de bifurcação dupla dos seus daemons, basta adicionar uma opção de linha de comando (como -f , -F ou --foreground ) que pula o código de daemonizing e executa o programa em primeiro plano. Use essa opção em seu arquivo de serviço systemd.

(Essa opção também seria útil ao executar o daemon para depuração ou solução de problemas de qualquer maneira.)

O Type=forking do systemd é capaz de trabalhar com daemons duplos de bifurcação, mas no final, existe apenas para compatibilidade. Há vantagens em não bifurcar (é mais fácil rastrear o processo principal), portanto, se você for capaz de modificar seu programa, é melhor fazê-lo.

    
por 19.10.2018 / 20:30