mensagem “matou” do cron.daily, mas não quando executado a partir da linha de comando

1

No Fedora 17, eu coloco um arquivo em /etc/cron.daily com o seguinte conteúdo:

cd /
su dstahlke /home/dstahlke/bin/anacron-daily.sh
exit 0

Por alguma razão, recebo uma correspondência todos os dias que diz apenas

/etc/cron.daily/dstahlke-daily:

 ...killed.

Eu tentei com e sem a linha exit 0 acima (notei que alguns scripts do sistema têm isso e outros não, não tenho certeza do propósito). Executar /etc/cron.daily/dstahlke-daily da linha de comando como raiz não produz nenhuma mensagem ...killed . Além da mensagem, tudo parece funcionar bem. Colocar set -x no script acima, assim como no script /home/dstahlke/bin/anacron-daily.sh , mostra que a mensagem ...killed acontece logo após o término do último script (ou talvez logo após o término do comando su).

O que causa a mensagem ...killed ?

Ou existe uma maneira mais aceitável de fazer com que o anacron execute um script de usuário diariamente? Imaginei que colocar isso em /etc/cron.daily ajudaria o sistema a coordenar todas as tarefas diárias, em vez de potencialmente executar minha tarefa simultaneamente com as tarefas do sistema.

    
por Dan Stahlke 15.09.2012 / 16:31

1 resposta

2

Eu fiz mais algumas investigações, e descobri que ...killed é realmente impresso pelo programa su , embora a impressão não venha do projeto coreutils upstream, ele é introduzido pelo coreutils-8.5-pam.patch no fonte rpm. Há alguma história sobre as origens para adicionar isso no bugzilla ( 622700 , 597928 e 240117 ).

A parte relevante do código é

static sig_atomic_t volatile caught_signal = false;
...
/* Signal handler for parent process.  */
static void
su_catch_sig (int sig)
{
  caught_signal = true;
}

...

static void
create_watching_parent (void)
{
  ...
  sigfillset (&ourset);
  if (sigprocmask (SIG_BLOCK, &ourset, NULL))
    {
      error (0, errno, _("cannot block signals"));
      caught_signal = true;
    }
  if (!caught_signal)
    {
       ...
       action.sa_handler = su_catch_sig;
       ...
         || sigaction (SIGTERM, &action, NULL)
 ...
  if (caught_signal)
    {
      fprintf (stderr, _("\nSession terminated, killing shell..."));
      kill (child, SIGTERM);
    }

  cleanup_pam (PAM_SUCCESS);

  if (caught_signal)
    {
      sleep (2);
      kill (child, SIGKILL);
      fprintf (stderr, _(" ...killed.\n"));
    }
  exit (status);
}

Portanto, de alguma forma (direta ou indiretamente relacionada a cleanup_pam ou não relacionada) o processo pai recebe SIGTERM entre o segundo último e o último se testes e, portanto, imprime apenas a mensagem ...killed que obviamente deveria ter sido uma continuação de o fprintf acima.

Apesar de tudo, o uso duplo de caught_signal como um manipulador de sinal assíncrono significa e como uma variável de controle de fluxo local dentro da função parece um hack realmente sujo e eu não gostei do código. Eu testei dividindo isso e introduzi uma variável booleana kill_child para usar no corpo da função e depois ter

  if (caught_signal)
    {
kill_child:
      kill_child = true;
      status = 1;
    }

  if (kill_child) {
    {
      fprintf (stderr, _("\nSession terminated, killing shell..."));
      kill (child, SIGTERM);
    }

  cleanup_pam (PAM_SUCCESS);

  if (kill_child)
    {
      sleep (2);
      kill (child, SIGKILL);
      fprintf (stderr, _(" ...killed.\n"));
    }
  exit (status);
}

no final da função. Com essa modificação eu não recebo mais ....killed spam de anacron.

Portanto, uma longa explicação e possivelmente mais informações do que você precisa. Contudo. Eu também descobri um pouco mais, o que é uma boa notícia para você, já que você não precisa fazer modificações locais no pacote coreutils. Para casos como executar o su do cron, você deve rodar o programa runuser instead . É uma espécie de notícia "ruim" para mim, pois torna minhas descobertas acima menos importantes, mas bem bem:).

    
por 27.12.2012 / 01:04

Tags