Como reiniciar (ou redefinir) um processo em execução no linux

5

Eu tenho dois sistemas Linux se comunicando através de sockets (desktop e placa de desenvolvimento baseada em ARM).

Eu quero reiniciar (ou redefinir) meu aplicativo cliente (em execução em uma placa de desenvolvimento) quando o servidor envia uma mensagem predefinida específica. Eu não quero reiniciar (reboot) o Linux, eu só quero que o aplicativo cliente reinicie a si mesmo automaticamente.

Não consigo entender como isso deve ser feito.

    
por Saad Rafey 06.06.2015 / 12:30

3 respostas

5

A maneira normal de fazer isso é deixar o programa sair e usar um sistema de monitoramento para reiniciá-lo. O programa init oferece esse sistema de monitoramento. Existem muitos programas init diferentes (SysVinit, BusyBox, Systemd, etc.), com mecanismos de configuração completamente diferentes (sempre escrevendo um arquivo de configuração, mas o local e a sintaxe do arquivo são diferentes), então procure a documentação do arquivo que você está usando. Configure o init para iniciar seu programa no momento da inicialização ou mediante solicitação explícita e reiniciá-lo se ele morrer. Há também programas de monitoramento mais sofisticados, mas você não parece precisar deles. Essa abordagem tem muitas vantagens em ter o programa fazendo a reinicialização por si só: é padrão, para que você possa reiniciar vários serviços sem precisar se preocupar com como eles são feitos; funciona mesmo se o programa morrer devido a um bug.

Há um mecanismo padrão para que um processo saia: sinaliza . Envie seu programa um sinal TERM. Se o seu programa precisar executar alguma limpeza, escreva um manipulador de sinal. Isso não impede que um comando específico do programa seja desativado se você tiver um canal administrativo para enviar comandos desse tipo.

    
por 06.06.2015 / 23:05
5

Faça o seu cliente exec /proc/self/exe quando receber essa mensagem paticular. Você não precisa saber onde o executável realmente reside no sistema de arquivos. E você pode reutilizar main() ' argv para construir um novo vetor de argumentos.

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
        char buf[32] = {};
        char *exec_argv[] = { argv[0], buf, 0 };
        int count = argc > 1 ? atoi(argv[1]) : 0;

        printf("Running: %s %d\n", argv[0], count);
        snprintf(buf, sizeof(buf), "%d", count+1);
        sleep(1);

        execv("/proc/self/exe", exec_argv);

        /* NOT REACHED */
        return 0;
}

Este restart.c é executado assim:

$ gcc restart.c 
$ ./a.out 3
Running: ./a.out 3
Running: ./a.out 4
Running: ./a.out 5
    
por 06.06.2015 / 13:56
2

Se o aplicativo cliente for um serviço do Linux, ele poderá ser reiniciado com este comando:

service <clientapp> restart

ou forçado a recarregar sua configuração:

service <clientapp> reload
service <clientapp> force-reload

Se, mais provavelmente, for um aplicativo personalizado, ele precisa ter incorporado em seu código o recurso para reiniciar ou recarregar sua configuração na recepção de um sinal ou evento. Se não o fizer, como último recurso, pode sempre eliminar a aplicação do cliente:

pkill -9 <clientapp>

e reinicie novamente, mas é feio quando deixa o aplicativo em um estado indeterminado.

    
por 06.06.2015 / 12:57