3.8. Daemons, sinais e controle de processos

Ao usar um editor, é fácil controla-lo, indicar que ele deve carregar arquivos, e assim por diante. Você pode fazê-lo pois o editor oferece algumas opções para fazê-lo, e por que o editor é diretamente interligado a um terminal. Alguns programas não são projetados de forma a utilizar informações contínuas do usuário, e assim ele se desconecta do terminal em sua primeira oportunidade. Por exemplo, um servidor HTTP passa o tempo todo respondendo requisições da rede, e normalmente ele não necessita intervenção alguma do usuário. Programas que transportam mensagens de correio de um local para outro, são outro exemplo dessa classe de aplicações.

Chamamos estes programas de daemons. Daemons são personagens da mitologia Grega; não são bons, nem maus, eram apenas espíritos assistentes que, na maior parte do tempo, realizavam tarefas úteis para a humanidade. É por isso que o mascote do BSD, há um bom tempo, é aquele daemon simpático que usa tênis e carrega um tridente.

Existe uma convenção para batizar os programas que normalmente são executados como daemon, que é terminar o nome do programa com um ``d''. BIND é o Daemon de Nomes Internet de Berkeley, (Berkeley Internet Name Daemon - o programa que o executa, é chamado named), O servidor WWW Apache é chamado de httpd, o daemon de impressão em linha é o lpd e assim sucetivamente. Esta é uma convenção, e não uma regra de rápida assimilação; por exemplo, o daemon principal para a aplicação Sendmail é chamado sendmail, e não maild, como você poderia ter imaginado inicialmente.

Algumas vezes será necessário se comunicar com um processo daemon. Essa comunicação é chamada de sinais, e você pode se comunicar com o daemon (ou qualquer outro processo em execussão) enviando-o um sinal. Existem uma série de sinais diferentes que podem ser enviados--alguns dos quais tem um significado específico, e outros são interpretados pela aplicação, e a documentação dessa aplicação indicará o que ela faz quando recebe este tipo de sinal. Você só pode enviar um sinal para os processos que te pertencem. Se você tentar enviar sinais para um processo que não é seu, com kill(1) ou kill(2) terá permissão negada. A única excessão é o usuário root, que pode enviar sinais para os processos de todos.

O FreeBSD em certos casos também enviará sinais às aplicações. Se uma aplicação for mal escrita e tentar acessar endereços de memória que ele não deve, o FreeBSD envia o sinal de violação de segmento ao processo (Segmentation Violation), conhecido como SIGSEGV. Se alguma aplicação usou a chamada de sistema alarm(3) para solicitar que seja alertada depois de certo período de tempo, o sistema envia o sinal de alerta (SIGALRM) ao processo, e assim por diante.

Dois sinais podem ser usados para interromper um processo, SIGTERM e SIGKILL. SIGTERM é uma maneira educada de matar um processo; o processo pode acatar o sinal, entender que você deseja que ele deixe de ser executado, fechar qualquer arquivos de logs que ele tenha aberto, e geralmente terminar a tarefa que ele está realizando no momento, antes de deixar de executar. Em alguns casos um processo pode ignorar o SIGTERM se ele estiver no meio de uma tarefa que não pode ser interrompida.

SIGKILL não pode ser ignorado por qualquer processo. Este é o sinal que diz ao processo, ``Eu não me importo com o que você esteja fazendo, pare agora mesmo''. Se você enviar um SIGKILL a qualquer processo, o FreeBSD irá interromper aquele processo[1].

Outros sinais que você pode querer conhecer são SIGHUP, SIGUSR1, e SIGUSR2. Estes são sinais de propósitos gerais, e aplicações distintas terão comportamento distintos ao receber estes sinais.

Suponha que você modificou o arquivo de configuração do seu servidor HTTP--você deseja dizer ao daemon para ele reler essa configuração. Você poderia parar e reiniciar o httpd, mas isso resultaria em uma breve interrupção do serviço, o que pode não ser desejável. A maioria dos daemons são escritos de forma que respondam a um SIGHUP com a releitura de seu arquivo de configuração. Então, ao invés de matar e reiniciar o processo httpd você enviaria o sinal SIGHUP ao processo. Por não existir uma forma padrão de resposta à estes sinais, cada daemon pode ter um comportamento diferente, de forma que você deve ler a documentação para o programa em questão.

Sinais são enviados utilizando o comando kill(1), como mostra o exemplo a seguir:

Enviando sinal aos processos

Esse exemplo mostra como enviar sinais ao inetd(8). O arquivo de configuração do inetd é o /etc/inetd.conf, e o inetd irá reler sua configuração, quando receber o sinal SIGHUP.

  1. Encontre o ID do processo que você quer enviar o sinal. Faça isso com o ps(1) em conjunto com grep(1). O grep(1) é usado para procurar por uma cadeia de caracteres na saída desejada. O comando é executado como usuário normal, e o inetd(8) é executado como root, então as opções ax devem ser usadas com o ps(1).

    % ps -ax | grep inetd
      198  ??  IWs    0:00.00 inetd -wW
    

    Portando o PID do inetd(8) é 198. Em alguns casos o comando grep inetd poderá estar incluso também na saída desses comandos. Isso se deve à maneira como o ps(1) procura na lista de processos em execussão.

  2. Use kill(1) para enviar sinais. Pelo fato do inetd(8) estar sendo executado pelo root você deve usar o su(1) antes, para se tornar root.

    % su
    Password:
    # /bin/kill -s HUP 198
    

    Como de costume com a maioria dos comandos UNIX®, o kill(1) não apresentará qualquer mensagem se o resultado da ação for bem sucedido. Se você enviou um processo que não é seu, você verá uma mensagem parecida com ``kill: PID: Operation not permitted''. Se você digitar o PID errôneamente, ou você vai enviar o sinal ao processo errado, o que pode ser bem ruim, ou, se você tiver sorte, terá enviado o sinal a um processo que não está ativo, e verá algo como ``kill: PID: No such process''.

    Por que usar o /bin/kill?: Muitos interpretadores de comandos oferecem o comando kill embutido; ou seja, o interpretador enviará o sinal diretamente, ao invés de executar o /bin/kill. Isso pode ser muito útil, mas interpretadores de comandos distintos podem ter sintaxe distinta. Ao invés de aprender a usar cada uma, é bem mais fácil aprender usar o comando /bin/kill ... diretamente.

Enviar outros sinais é muito parecido, basta substituir o TERM ou KILL na linha de comando, conforme for necessário.

Importante: Matar processos aleatórios no sistema pode ser uma má idéia. Em especial o processo cujo ID é 1, o init(8), que é bem particular. Enviar um /bin/kill -s KILL 1 é uma forma singela de desligar seu sistema. Sempre verifique duas vezes os argumentos do kill(1) antes de apertar Enter.

Notas

[1]

Não é completamente verdade--existem algumas poucas tarefas que não podem ser interrompidas. Por exemplo, se o processo está tentando ler um arquivo que está em uma outra estação da rede, e essa outra estação não está mais disponível por alguma razão (foi desligado, ou houve falha na rede), então o processo é definido como um processo que não pode ser interrompido. Eventualmente ele irá passar do tempo máximo de atividade permitida, tipicamente dois minutos (o timeout). Tão logo este período aconteça, o processo é morto.

Este, e outros documentos, podem ser obtidos em ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

Para perguntas sobre FreeBSD, leia a documentação antes de contatar <questions@FreeBSD.org>.
Para perguntas sobre esta documentação, envie e-mail para <doc@FreeBSD.org>.