Como escrever um script de parada personalizado runit

12

Eu quero ter um script "stop" personalizado runit( runsv) para executar quando precisar parar / reiniciar o processo. Atualmente, ele simplesmente mata o processo e, em seguida, executa o script "finish". Mas, no meu caso, meu processo gera processos filho dinamicamente; portanto, em vez de simples kill, eu preciso "killtree"me livrar deles. Como faço isso?

Eu sei que isso deve ser feito através das controlopções do runit, mas, ao ler os documentos, não está muito claro para mim como o script de parada deve ser nomeado :(

http://smarden.org/runit/runsv.8.html

ddinchev
fonte
Seu serviço (não o script, mas o programa) parece ter um comportamento inadequado; ele deve colher / limpar após os próprios filhos. Apenas curioso, o que é isso?
Avery Payne

Respostas:

13

Dos documentos

Para cada caractere de controle c enviado ao tubo de controle, o runsv primeiro verifica se service / control / c existe e é executável. Nesse caso, inicia service / control / ce aguarda o término, antes de interpretar o comando. Se o programa sair com o código de retorno 0, o runsv evita enviar ao serviço o sinal correspondente. O comando o é sempre considerado como comando u. No comando d, primeiro serviço / controle / t é verificado e, em seguida, serviço / controle / d. No comando x primeiro serviço / controle / t é verificado e, em seguida, serviço / controle / x. O controle do serviço de log opcional não pode ser personalizado.

Isso significa que você precisa criar um service_name/control/XX sendo um executável que será executado quando você enviar o svcomando relacionado ao serviço, como o dcomando (inativo). Se o seu script sair com o status 0, ele não tentará desativar o próprio serviço.

Basicamente, você precisa de um script executável /etc/sv/<service>/control/dque faça o que quiser e acabe com o serviço, limpe pids e etc.

coredump
fonte
é realmente interessante e simples do jeito que o runsv dir funciona.
Dzung Nguyen
2

A resposta simples é nomear seu script de limpeza como "serviço / acabamento". Este script é executado quando "service / run" sai.

Também existe uma interface "service / control / ctrl_char. Permite executar ações diferentes, dependendo de qual comando você envia para runsv.

Rik Schneider
fonte
1
O serviço / término é executado após o envio do TERM CONT para o serviço em execução. É mais como limpar o serviço após matar.
MaximKostrikin
2

Eu mesmo tive que resolver esse problema no docker. Eu tinha o servidor uwsgi em execução e ele recebeu o sinal errado pelo docker (TERM em vez de INT) ao parar o contêiner.

A idéia dos arquivos control / x é reagir a um sinal recebido. No meu caso, eu colocaria um tarquivo para o sinal final sob controle, uma vez que é o arquivo reservado para o termo sinal. O script deve ser executável.

#!/bin/bash
kill -INT `cat /tmp/project-master.pid`

O script envia um sinal int para o processo uwsgi, que é o que eu quero.

Se o script de controle estiver saindo sem erro (código de retorno 0), o sinal original não será enviado ao processo.

Portanto, no meu caso, eu pude receber o termo sinal e enviar um sinal int para o processo de serviço.

itsafire
fonte