Gerenciamento de processos e pkill

3

Estou estudando o gerenciamento de processos usando scripts de shell e estou começando a perceber o quanto é difícil garantir que seja feito corretamente.

Por exemplo, você pode gravar o PID de um programa em um arquivo, wait , e limpar o arquivo PID após a saída do programa.

Se você tentasse e kill este daemon de um script de inicialização, por exemplo, poderia pensar em fazer algo assim:

do_stop() {
  kill $(</var/run/program.pid)
}

Isso obviamente não funciona. Entre obter o PID e enviar o sinal de morte, outro processo poderia ter morrido e tomado seu lugar.

A maneira correta parece exigir o uso de IPC no pai do programa para enviar um sinal de morte para seu filho. Isso garantirá que o PID do processo não tenha sido reutilizado por outro.

Eu tenho tentado escrever meus próprios scripts de inicialização que são o mais corretos possível. Neste caso, eu tenho escrito um para o NRPE. O NRPE infelizmente daemoniza e se desativa no init, o que significa que não posso wait nele. Em vez disso, criei a seguinte solução:

do_stop() {
  echo "Stopping (sending SIGTERM to) nrpe"
  pkill -u nrpe || { echo >&2 "nrpe isn't running"; exit 1; }
}

O único processo que o usuário nrpe executa é o próprio NRPE, e considerando que o sistema está sob meu controle, considero esta uma solução relativamente sã.

Estou curioso sobre a atomicidade de pkill (se essa é a palavra certa a ser usada). Presumo que pkill siga estes passos:

  1. Pesquisa o PID na tabela de processos depois de analisar os argumentos para os critérios do processo.
  2. Envia SIGTERM (por padrão) para o PID obtido

Digamos que pkill -u nrpe dê um PID de 42 no passo 1. É possível que o processo de nrpe possa morrer e outro possa aparecer em seu lugar antes que o passo 2 ocorra?

    
por AlephBeth 03.07.2014 / 15:15

1 resposta

1

Você está correto ao suspeitar que há um problema (pequeno!) de atomicidade.

Não importa qual método você use, seja um utilitário padrão do sistema como start-stop-daemon , um arquivo PID roll-your-own, usando pkill para consultar e matar por ID do usuário, por binário executável ou qualquer outra coisa, há sempre um intervalo entre descobrir qual processo você quer matar e dar a ID do processo à chamada do sistema kill para enviar um sinal.

Basicamente, você não deve se preocupar com isso. Para ter problemas, ambos dos seguintes itens teriam que acontecer:

  • O processo de destino morre entre o momento em que você identifica seu ID de processo e a hora em que você realmente o elimina.
  • Os IDs do processo para o processo recém-criado precisariam, durante o mesmo intervalo de tempo, circular para reutilizar o ID do processo que acabou de ser desocupado.

É muito improvável.

Observe que, no caso específico em que você está estudando, você realmente tem uma maneira de se proteger contra isso. O único processo executado pelo usuário nrpe é o próprio NRPE, portanto, se você alternar para o usuário nrpe (de root , provavelmente) antes de emitir o comando kill , talvez sob circunstâncias muito improváveis tente para matar um processo inocente e pobre que pertence a outra coisa, mas você não terá permissão para fazê-lo e isso não terá nenhum efeito.

    
por 03.07.2014 / 21:34