Obtenha o código de saída dos processos bifurcados do processo mestre

4

Eu tenho um processo mestre ( run-jobs below) que inicia outros jobs como seus subprocessos. Quando o processo mestre falha (por exemplo, falha do banco de dados), ele sai com um código de status diferente de 0, o que é bom, e pode ser verificado examinando $? variable ( echo $? ).

No entanto, eu também gostaria de inspecionar os códigos de saída dos subprocessos caso a tarefa mestre falhe. Existe uma maneira conveniente de verificar o código de saída de process_1 e process_2 abaixo, uma vez que o processo mestre foi embora?

Esta é uma saída simplificada de ps auxf :

vagrant 5167 | \_ php app/console run-jobs vagrant 5461 | \_ php process_1 vagrant 5517 | \_ php process_2

    
por luqo33 11.08.2016 / 13:43

1 resposta

3

Processos relatam seu status de saída para seu pai e se seu pai está morto para o processo de id 1 ( init ), embora com versões recentes do Linux (3.4 ou acima), você possa designar outro ancestral como o para essa função (usando prctl(PR_SET_CHILD_SUBREAPER) ).

Na verdade, depois que eles morrem, os processos se tornam zumbis até que seu pai (ou init ) recupere seu status de saída (com waitpid() ou outro).

No seu caso, você está dizendo que as crianças estão morrendo depois (como resultado de?) run-jobs morrendo. Isso significa que eles reportarão seu status de saída para init ou para o processo designado como subcorpo filho.

Se init não registra isso (e geralmente não o faz) e se você não usa auditoria ou contabilidade de processo, esse status de saída será perdido.

Se em uma versão recente do Linux, você pode criar seu próprio sub-reaper para obter o status pid e exit desses processos órfãos. Como com perl :

$ perl -MPOSIX -le '
  require "syscall.ph";
  syscall(&SYS_prctl,36,1) >= 0 or die "cannot set subreaper: $!";

  # example running 1 child and 2 grand children:
  if (!fork) {
    # There, you would run:
    # exec("php", "run-jobs");
    if (!fork) {exec "sleep 1; exit 12"};
    if (!fork) {exec "sleep 2; exit 123"};
    exit(88)
  }
  # now reporting on all children and grand-children:
  while (($pid = wait) > 0) {
   print "$pid: " . WEXITSTATUS($?)
  }'
22425: 88
22426: 12
22427: 123

Se você quisesse recuperar informações sobre os processos de morte (como linha de comando, usuário, ppid ...), você precisaria fazer isso enquanto eles ainda estivessem no estado zumbi, ou seja, antes de você ter feito um wait() neles.

Para isso, você precisa usar a API waitid() com a opção WNOWAIT (e, em seguida, obter as informações do comando /proc ou ps ). Eu não acho que o perl tenha uma interface para isso, então você precisaria escrevê-lo em outro idioma como C .

    
por 11.08.2016 / 15:03