Comment écrire un script d'arrêt personnalisé runit

12

Je veux avoir un script runit( stop runsv) personnalisé à exécuter lorsque je dois arrêter / redémarrer le processus. Actuellement, il tue simplement le processus, puis exécute le script "finish". Mais dans mon cas, mon processus génère dynamiquement des processus enfants, donc au lieu de simples kill, j'ai besoin d'un "killtree"pour les supprimer. Comment je fais ça?

Je sais que cela devrait être fait via les controloptions de runit, mais à la lecture des documents, je ne sais pas vraiment comment le script d'arrêt doit être nommé :(

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

ddinchev
la source
Votre service (pas le script mais le programme) semble mal conduit, il devrait récolter / nettoyer après ses propres enfants. Juste curieux, c'est quoi?
Avery Payne

Réponses:

13

À partir des documents

Pour chaque caractère de contrôle c envoyé au canal de contrôle, runsv vérifie d'abord si service / control / c existe et est exécutable. Si c'est le cas, il démarre service / control / c et attend qu'il se termine, avant d'interpréter la commande. Si le programme se termine avec le code retour 0, runsv s'abstient d'envoyer au service le signal correspondant. La commande o est toujours considérée comme la commande u. Sur commande d, le premier service / contrôle / t est vérifié, puis le service / contrôle / d. Sur commande x, le premier service / contrôle / t est vérifié, puis le service / contrôle / x. Le contrôle du service de journalisation facultatif ne peut pas être personnalisé.

Cela signifie que vous devez créer un service_name/control/X, X étant un exécutable qui s'exécutera lorsque vous enverrez la svcommande associée au service, comme la dcommande (vers le bas). Si votre script se termine avec le statut 0, il n'essaiera pas d'arrêter le service lui-même.

Fondamentalement, vous avez besoin d'un script exécutable /etc/sv/<service>/control/dqui fera ce que vous voulez et tuera le service, nettoiera les pids, etc.

coredump
la source
c'est vraiment intéressant et simple la façon dont fonctionne dir dir.
Dzung Nguyen
2

La réponse simple est de nommer votre script de nettoyage "service / finish". Ce script est exécuté lorsque "service / run" se termine.

Il existe également une interface "service / contrôle / ctrl_char. Elle vous permet d'effectuer différentes actions selon la commande que vous envoyez à runsv.

Rik Schneider
la source
1
service / finish s'exécute après l'envoi de TERM CONT au service en cours d'exécution. C'est plus comme effacer le service après la mise à mort.
MaximKostrikin
2

J'ai dû résoudre ce problème moi-même pour docker. J'ai eu un serveur uwsgi en cours d'exécution, et il a été envoyé le mauvais signal par docker (TERM au lieu d'INT) lors de l'arrêt du conteneur.

L'idée des fichiers control / x est de réagir à un signal reçu. Dans mon cas, je placerais un tfichier pour le signal de terminaison sous contrôle, car c'est le fichier réservé au signal de terme. Le script doit être exécutable.

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

Le script envoie un signal int au processus uwsgi, ce que je veux.

Si le script de contrôle se termine sans erreur (code retour 0), le signal d'origine ne sera pas envoyé au processus.

Ainsi, dans mon cas, j'ai pu recevoir le terme signal et envoyer un signal int au processus de service à la place.

itsafire
la source