Qual é a melhor maneira de limpar depois de uma bomba de garfo?

21
$ ls
bash: no more processes

Ah, oh. Parece que alguém fez uma bomba de garfo. Onde eu costumava trabalhar, isso significava que o servidor compartilhado precisaria ser ligado e ligado, pois nem mesmo os administradores de sistema com root conseguiam resolver o problema. Muitas vezes, eles nem conseguiam receber um aviso.

Ouvi alguns truques (principalmente para enviar sinais STOP em vez de KILL, já que o último permitiria que os threads restantes substituíssem imediatamente os mortos), mas nunca vi um guia completo intitulado So, You Have Yourself uma bomba de garfo?

Vamos fazer um.

raldi
fonte

Respostas:

10

Evite que o fork pump esgote o limite do processo com um limite razoável de processo por usuário usando ulimit .

Dessa forma, um único usuário esgotará sua cota de processo muito antes do limite do sistema ser atingido.

Chris Smith
fonte
6

A primeira coisa a tentar seria fazer com que os usuários conectados efetuassem logout. É possível que o shell deles seja o processo pai do processo, fazendo todo o processo de bifurcação e isso pode acabar com o problema.

Se isso não funcionar, você pode tentar executar kill -STOP -2como root para congelar todos os processos em execução como qualquer usuário que não seja root. Se isso funcionar, você poderá kill -CONT <pid>descongelar alguns processos conhecidos que não estão relacionados à bomba de forquilha e eliminá-los para eliminar o problema completo da tabela de processos e dar a você um espaço para respirar para rastrear e eliminar a fonte original do problema. O Sendmail seria um bom exemplo de um processo do sistema a ser eliminado, pois seria fácil identificar usando o arquivo .pid para identificar o pid. Por exemplo kill -CONT $(< /var/run/sendmail.pid); kill $(< /var/run/sendmail.pid),.


fonte
Em qual SO você vê uma opção "-2" para matar? Eu não vejo isso na página de manual no Linux.
raldi
1
Isso deve funcionar na maioria dos sistemas operacionais, pois você especifica um valor negativo para o pid. Se <pid> for menor que -1, o kill será enviado a todos os processos no grupo de processos - <pid>. Ao enviar um sig de STOP para o pid -2, ele deve parar todos os processos que não são processos especiais do sistema ou processos de propriedade raiz.
Veja a página de manual kill (2) por matar um "pid negativo", mas ainda não acredito que isso funcione. Por que todos os processos não init estariam no grupo 2? Eu entendo que você gostaria de evitar o init, já que os resultados de interrompê-lo são muitas vezes bastante fatal, mas ...
ephemient
@hemhemient, 2 é muito baixo para ser um ID de grupo de processos, então talvez seja outro valor especial.
joshudson
@ Joshua Não há valores especiais ao lado 0e -1, de acordo com opengroup.org/onlinepubs/009695399/functions/kill.html opengroup.org/onlinepubs/000095399/utilities/kill.html
ephemient
3

Não tenho certeza de como você pode enviar um sinal de STOP, pois a geração killexigiria um identificador de processo disponível. Além disso, na minha experiência, os sistemas ficam sobrecarregados e inutilizáveis ​​muito antes de ficar sem processos.

Você já pensou em impor limites de processo por usuário ulimit? Isso impediria que seus usuários lançassem bombas de forquilha (acidentalmente ou não).

John Millikin
fonte
3
kill é um shell embutido, pelo menos no bash.
raldi 7/10/08
1
Eu acho que esse é um componente essencial - identifique os componentes internos para o seu shell de escolha.
2
Se não for um built-in, você pode executar "exec kill PID", o que não ocorre na bifurcação. Mas é arriscado, pois, se não funcionar, você poderá não conseguir outro shell. Pense nisso como a abordagem mais difícil da administração do sistema!
18119 Stephen Darlington
2

Alguns sistemas BSD têm a capacidade de reservar os últimos 5 ou mais processos para raiz. Talvez o seu sistema tenha essa capacidade.

Joshudson
fonte
3
Como você realmente configura o sistema para fazer isso?
58680 Nik Kingman