Melhor maneira de fazer um gancho de desligamento?

9

Como o Ubuntu conta com o upstart já há algum tempo, eu gostaria de usar um trabalho inicial para encerrar normalmente certos aplicativos no desligamento ou reinicialização do sistema. É essencial que o desligamento ou reinicialização do sistema seja interrompido até que esses aplicativos sejam desligados.

Os aplicativos serão iniciados manualmente ocasionalmente e o desligamento do sistema deve ser encerrado automaticamente por um script (que eu já tenho). Como os aplicativos não podem ser finalizados de maneira confiável sem (quase todos) outros serviços em execução, o término dos aplicativos deve ser feito antes que o restante do desligamento comece.

Penso que posso resolver isso através de um trabalho inicial que será acionado no encerramento, mas não tenho certeza de quais eventos devo usar de que maneira. Até agora, li as seguintes declarações (parcialmente contraditórias):

  • Não há evento de desligamento geral no iniciante
  • Use uma estrofe como start on starting shutdownna definição de tarefa
  • Use uma estrofe como start on runlevel [06S]na definição de tarefa
  • Use uma estrofe como start on starting runlevel [06S]na definição de tarefa
  • Use uma estrofe como start on stopping runlevel [!06S]na definição de tarefa

A partir dessas recomendações, surgem as seguintes perguntas:

  • Existe ou não um evento de desligamento geral no inicio do Ubuntu?
  • Qual é a maneira recomendada de implementar um "gancho de desligamento"?
  • Quando os eventos no nível de execução [x] são acionados; é isso ao entrar no nível de execução ou ao entrar no nível de execução?
  • Podemos usar algo como start on starting runlevel [x]ou start on stopping runlevel [x]?
  • Qual seria a melhor solução para o meu problema?

Muito obrigado

Binarus
fonte

Respostas:

2

startinge runlevelsão eventos separados, então você não pode dizer de maneira significativa starting runlevel N.

O runlevel Nevento é emitido no início da entrada no nível de execução. Se você start on runlevel N, sua tarefa for executada na entrada. A maneira de executar quando a entrada no nível de execução é concluída é run on started rc RUNLEVEL=N.

Pelo que entendi, você precisa start on runlevel [06S]fazer o que quiser; em teoria, deveria correr antes que qualquer outra coisa fosse interrompida. Para um controle mais preciso, você pode usar start on stopping apache or stopping mysql or ...para que sua tarefa seja executada antes que qualquer uma delas possa ser desligada.


Editado para alterar o nível de execução 5 para S.

geekosaur
fonte
1
Além disso, a única razão pela qual há um startupevento distinto é que algo é necessário para "escorvar a bomba". Depois que um evento privilegiado é enviado, tudo o mais pode ser e é definido pelos trabalhos e tarefas acionados por startup. Quanto a não haver um único shutdownevento, existem muitos tipos diferentes shutdownpara que isso seja significativo. É melhor depender diretamente dos trabalhos que você precisa executar.
Geekosaur 14/03
Muito obrigado. Aceito sua resposta com gratidão, pois ela responde às minhas perguntas e resolve o problema. No entanto, tenho uma pergunta / comentário adicional (que não está relacionado a um problema): AFAIK, é objetivo do iniciante substituir completamente o conceito de nível de execução. O fato de que precisamos confiar nos níveis de execução para obter um gancho de desligamento global contradiz esse objetivo. Eu acho que o iniciante terá que apresentar esse evento. Eu estou entendendo claramente que seria melhor que depender dos trabalhos que realmente precisamos, mas, por outro lado, no meu caso, é um monte de postos de trabalho ... cont ...
Binarus
(quase tudo o que está sendo executado), e nem me atrevo a pensar em descobrir a relação entre os processos em execução na caixa (ps-Alf) e os trabalhos que controlam esses processos; com certeza não há relação 1: 1. Existem trabalhos que não estão relacionados a nenhum processo (configurando a rede, por exemplo), e suponho que haja processos suficientes que não estejam relacionados a trabalhos de qualquer maneira e especialmente ao iniciar as coisas manualmente.
Oli
O Upstart substituiu os níveis de execução codificados ; Até onde eu sei, o conceito de nível de execução não está desaparecendo, está definido no espaço do usuário agora. Se você está preocupado com um prazo tão longo, deseja usar minha última sugestão de execução on stopping servicea or stoping serviceb or ...para os serviços que você precisa executar.
Geekosaur
-1 para várias imprecisões. Simplesmente, isso não vai realmente funcionar. stop on start rc RUNLEVEL = [016] não é diferente de 'stop on runlevel [016]'. Isso ocorre porque nenhum dos eventos impedirá o prosseguimento do desligamento. Também há sintaxe inválida, pois 'executar' não é válido. Tudo isso apenas confunde o problema, na verdade não ajuda. Desculpe que seja tão tarde! Apenas revendo respostas antigas.
SpamapS
2

Para impedir que o desligamento continue enquanto seu trabalho é interrompido, você deve usar o seguinte:

stop on starting rc RUNLEVEL=[016]

Isso funcionará porque a primeira coisa que acontece quando você digita 'shutdown' é o nível de tunel 0 é emitido. rc inicia no nível de execução, e a transição de parado -> inicial será completamente bloqueada até que quaisquer tarefas que também devem mudar de estado concluam esse estado.

Você deseja garantir que seu processo responda rapidamente ao SIGTERM. Se não responder dentro de 5 segundos, o iniciante enviará o SIGKILL. Você pode aumentar isso com 'kill timeout X'.

O 1 ali, btw, é um pouco complicado, você precisa ter certeza de que o início inclui algo que inicie no nível de execução [2345] nesse ponto, para que um usuário que esteja inativo para manutenção no modo de usuário único inicie seu trabalho novamente. Felizmente, muito trabalho foi feito para tornar este o início usual sugerido em

start on runlevel [2345]

Também em alguns casos, você precisa de algo para continuar funcionando até a rede ser desativada (como dbus / network-manager). Para isso você quer

stop on deconfiguring-networking

Esse é um evento emitido posteriormente no encerramento que também será bloqueado até que quaisquer tarefas que o usem concluam completamente suas transições no estado.

SpamapS
fonte
Você quis dizer? start on starting ... Não faz muito sentido ter meu gancho de desligamento parado em nada. start on starting rc RUNLEVEL=[016]faria muito mais sentido. E talvez uma taskjogada lá para garantir que ela possa ser concluída antes que outras coisas funcionem.
Tejay Cardon
0

Geekosaur, muito obrigado pela sua ajuda.

Enquanto isso, tentei o start on runlevel [016]método, mas não funcionou e acho que entendo o porquê:

O trabalho foi realmente iniciado, mas o processo de desligamento não foi bloqueado até a conclusão da tarefa. Estou certo agora que os eventos startinge stoppingos únicos que podem ser usados ​​em uma definição de trabalho para bloquear outros trabalhos, e acho que é isso que os manuais da Upstart tentam nos dizer. Portanto, o uso do evento runlevel nunca levará ao bloqueio de outros trabalhos ou ao processo de desligamento; assim, é inútil para o meu propósito.

Em vez disso, pareço ter duas possibilidades:

  1. Seguindo uma de suas proposições, descubra todos os trabalhos de que os aplicativos respectivos precisam e inclua todos eles no evento start para o script assim:

    start on stopping job1 or stopping job2 or ...
    

    É tanto trabalho que estou pensando seriamente em descartar a lista de tarefas e executá-la no sed para produzir automaticamente uma estrofe de início para o meu trabalho, que inclui todos os trabalhos que normalmente estão em execução no sistema.

    A vantagem seria que os respectivos aplicativos seriam encerrados mesmo quando alguém parasse um dos pré-requisitos manualmente (em vez de interrompê-los por uma alteração / desligamento / reinicialização do nível de execução).

  2. Encontre o único trabalho que será parado primeiro ao reiniciar / desligar o sistema (vamos chamar esse trabalho de "FirstJob") e use esse trabalho em uma estrofe como:

    start on stopping FirstJob
    

    As principais desvantagens seriam que eu não sei se esse trabalho existe e se esse trabalho realmente depende de todos os outros trabalhos dos quais o aplicativo em questão realmente depende ("depende de outro trabalho", nesse caso, significa "será interrompido" completamente antes que outro trabalho comece a parar ").

Não tenho certeza de qual das duas possibilidades é a melhor ...

Binarus
fonte
Eu estaria fazendo o sedroteiro agora, se estivesse no seu lugar.
Geekosaur #