Como parar todos os processos filhos gerados por um serviço

Como parar todos os processos filhos gerados por um serviço

Tenho um serviço rodando no Ubuntu com a seguinte configuração:

#/etc/init/my_service.conf

start on (local-filesystems and net-device-up IFACE=eth1)

respawn

exec python -u /opt/XYZ/my_prog.py 2>&1 \
                 | logger -t my_prog.py

Ao interromper o serviço com sudo service my_service stop, o processo python não é eliminado. Eliminar o processo pai killtambém não elimina o processo python.

Como interrompo completamente o serviço (ou seja, todos os processos filhos eliminados)? Idealmente, eu gostaria de não modificar o arquivo de configuração acima.

Responder1

Idealmente, eu gostaria de não modificar o arquivo de configuração acima.

Difícil! É a coisa certa a fazer.

Você precisa mudar execpara scripte parar de executar esse programa python em um subprocesso bifurcado como parte de um pipeline. Esta resposta ServerFaultexplica como fazer isso em um script de shell incorporado. Eu faria apenas uma alteração no script fornecido ali, na última linha:

exec python -u /opt/XYZ/my_prog.py 2>&1

Afinal, não há uma boa razão para não registrar erros padrão também.

Giros cada vez mais complexos para lidar com a bifurcação, de expect daemonpara mudar para systemd, não entendemos que a coisa certa a fazer éimpedir o daemon de bifurcar. Se há algo de bom que resulta da confusão atual, é a contínua confirmação de que o que a IBM escreveu e recomendou em 1995 esteve certo durante todos esses anos.

Acostume-se com a ideia decarregamento em cadeiademônios. Existem muitos conjuntos de ferramentas que simplificam essas coisas. Acostume-se também com a ideia de não usar scripts de shell. Existem muitos conjuntos de ferramentas projetados especificamente para este trabalho, que eliminam as sobrecargas dos shells (que é uma boa ideia conhecida no mundo Ubuntu).

Por exemplo: Os comandos shell na resposta ServerFault podem ser substituídos por um script que usaexeclineFerramentas de Laurent Bercotque são projetados para serem capazes de fazer exatamente isso sem subshells e FIFOs desvinculados:

#!/command/execlineb -PW
pipeline -w {
    logger -t my_prog.py
} 
fdmove -c 2 1 
python -u /opt/XYZ/my_prog.py

que você simplesmente faria

exec /foo/this_execlineb_script

Commeu noshconjunto de ferramentas, seria semelhantemente um script contendo:

#!/usr/local/bin/nosh
pipe 
fdmove -c 2 1 
python -u /opt/XYZ/my_prog.py | logger -t my_prog.py

Ou, alternativamente, pode-se ter esta estrofe diretamente na definição da tarefa Upstart (usando um truque para evitar metacaracteres do shell para que o Upstart não gere um shell):

exec /usr/local/bin/exec pipe --separator SPLIT fdmove -c 2 1 python -u /opt/XYZ/my_prog.py SPLIT logger -t my_prog.py

Leitura adicional

Responder2

No GNU/Linux, normalmente, não há como parar um serviço e todos os processos filhos que ele gerou, porque os processos filhos podem alterar seu PPID (ID do processo pai). A única maneira de saber seriavestígioo sistema chama para gerar processos à medida que são criados e mantém uma lista desses processos.

O sistema init do Ubuntu upstartnão faz isso. Então a resposta para sua pergunta éé impossível-- no Ubuntu -- sem:

  1. Modificando esse script;
  2. Saber exatamente quais IDs de processo são gerados por esse processo;
  3. Acompanhar esses IDs de processo manualmente;
  4. Matando-os individualmente.

É por isso que você deve executar uma distribuição de Linux que executesistema. Como você pode ver, systemdacompanha todos os processos filhose pode matar cada um deles com um único comando. É assim que a administração do sistema GNU/Linuxdeveria estar, mas como o systemd é tão novo e porque é "Não inventado aqui" (ou seja, a Canonical não o inventou), o Ubuntu não quer usá-lo.

Responder3

Você pulou oesperarestrofe. Olivro de receitas inicianteespecifica:

Aviso

Esta estrofe é extremamente importante: leia esta seção com atenção!

O Upstart acompanhará o ID do processo que acredita pertencer a um trabalho. Se um trabalho tiver especificado a sub-rotina da instância, o Upstart rastreará os PIDs para cada instância exclusiva desse trabalho.

Se você não especificar a sub-rotina expect, o Upstart rastreará o ciclo de vida do primeiro PID executado nas sub-rotinas exec ou script. No entanto, a maioria dos serviços Unix irá "daemonizar", o que significa que eles criarão um novo processo (usando fork(2)) que é filho do processo inicial. Freqüentemente, os serviços farão uma "bifurcação dupla" para garantir que não tenham nenhuma associação com o processo inicial. (Observe que nenhum serviço fará um fork mais de duas vezes inicialmente, pois não há benefício adicional em fazê-lo).

Nesse caso, o Upstart deve ter uma maneira de rastreá-lo, então você pode usar expect fork ou expect daemon que permite ao Upstart usar ptrace(2) para "contar bifurcações".

Para permitir que o Upstart determine o ID final do processo para um trabalho, ele precisa saber quantas vezes esse processo chamará fork(2). O próprio Upstart não pode saber a resposta a esta pergunta, uma vez que uma vez que um daemon esteja em execução, ele poderá bifurcar vários processos "trabalhadores" que poderão eles próprios bifurcar inúmeras vezes. Não se pode esperar que o Upstart saiba qual PID é o "mestre" neste caso, considerando que ele não sabe se os processos de trabalho serão criados, muito menos quantas vezes ou quantas vezes o processo será bifurcado inicialmente. Como tal, é necessário informar ao Upstart qual PID é o PID “mestre” ou pai. Isso é conseguido usando a estrofe expect.

Você precisa disso porque o pipe |que você está usando está criando processos filhos. Você pode encontrar no livroProgramação Linux avançadauma breve introdução a isso, onde se afirma que:

Por exemplo, este comando shell faz com que o shell produza dois processos filhos, um paraeue um paramenos:

 $ ls | less

O que não sei é se isso implica uma ou duas bifurcações, então experimentaria modificar a linhareaparecimentono seu código com qualquer um

 expect fork
 respawn

ou

 expect daemon
 respawn

Eu não acredito que isso possa ser alcançadoapenascomsistema, embora meu logotipo mostre claramente que sou fã desistema.

informação relacionada