Comment détecter l'arrêt du système en attente sous Linux?
Je suis en train de travailler sur une application où j'ai besoin de détecter un arrêt du système.
Cependant, je n'ai pas trouvé de moyen fiable d'obtenir un avis sur cet événement.
Je sais qu'à l'arrêt, mon application recevrez un SIGTERM
signal suivie par un SIGKILL
. Je veux savoir si il existe un moyen pour interroger si un SIGTERM
est partie d'une séquence d'arrêt?
Ce que quelqu'un sait si il existe un moyen de requête par programmation (API C)?
Autant que je sache, le système ne fournit aucune autre méthode de requête pour un arrêt imminent. Si il n', qui permettrait de résoudre mon problème. J'ai essayé runlevels
ainsi, mais le changement dans runlevels
semblent être instantanée et sans avertissement préalable.
source d'informationauteur 341008
Vous devez vous connecter pour publier un commentaire.
Peut-être un peu de retard. Oui, vous pouvez déterminer si un signal SIGTERM est dans un arrêt de processus en invoquant la niveau d'exécution de commande. Exemple:
de l'enregistrer comme, disons,
term.sh
et de l'exécuter. Par l'exécution dekillall term.sh
vous devriez capable de voir et d'étudier larun-level
fichier dans votre répertoire home. Par l'exécution de l'une des opérations suivantes:et de comparer la différence dans le fichier. Alors vous devriez avoir l'idée sur comment le faire.
De l'homme de l'arrêt:
De sorte que vous pouvez tester l'existence de
/etc/nologin
. Il n'est pas optimal, mais probablement le meilleur que vous pouvez obtenir.Il n'y a aucun moyen de déterminer si un
SIGTERM
est une partie d'une séquence d'arrêt. Pour détecter une séquence d'arrêt, vous pouvez soit utiliserrc.d
des scripts comme ereOn et Eric Sepanson suggéré ou de l'utilisation des mécanismes comme DBus.Cependant, à partir d'une conception de point de vue, il ne fait aucun sens de l'ignorer
SIGTERM
même si elle ne fait pas partie de l'arrêt.SIGTERM
'objectif principal est de demandez poliment apps pour quitter proprement et il n'est pas probable que quelqu'un avec suffisamment de privilèges émettra unSIGTERM
si il/elle ne veut pas l'application à quitter.De faire votre demande de répondre différemment à certains SIGTERM signaux que les autres semble opaque et potentiellement source de confusion. On peut soutenir que vous devez toujours répondre de la même manière à un signal donné. L'ajout de conditions inhabituelles rend plus difficile de comprendre et de tester le comportement de l'application.
Ajout d'un script rc qui gère l'arrêt (par l'envoi d'un signal spécial) est un complètement de manière standard pour traiter un tel problème; si ce script est installé en tant que partie d'un paquet standard (
make install
ou rpm/deb emballage) il devrait y avoir aucun soucis sur le contrôle des machines des utilisateurs.C'est un peu un hack, mais si le serveur est en cours d'exécution systemd si vous pouvez l'exécuter
/bin/systemctl list-jobs shutdown.target
... il fera rapport ...
... si le serveur est en cours d'arrêt ou de redémarrage ( indice: il y a un redémarrage.cible si vous voulez un look plus précisément pour cela )
Vous obtiendrez
No jobs running.
si elle n'est pas en cours d'arrêt.Vous devez analyser la sortie, ce qui est un peu bordélique que le systemctl ne pas renvoyer un code de sortie différent pour les deux résultats. Mais il ne semble pas raisonnablement fiables. Vous aurez besoin de regarder pour un changement de format dans les messages si vous mettez à jour le système de toutefois.
Je pense que je l'ai eu.
Source =
https://github.com/mozilla-b2g/busybox/blob/master/miscutils/runlevel.c
Je copier une partie du code ici, juste au cas où la référence disparaît.
voir
man systemctl
vous pouvez déterminer si le système s'arrête comme ceci:c'est en bash, mais vous pouvez le faire avec le "système" en C
Lorsque le système s'arrête, le
rc.d
scripts sont appelés.Peut-être que vous pouvez ajouter un script il y qui envoie un signal spécial à votre programme.
Cependant, je doute que vous pouvez arrêter le système de l'arrêt de cette façon.
La réponse pratique à faire ce que vous vouliez à l'origine, c'est que vous vérifier le processus d'arrêt (e.g ps aux | grep "shutdown-h" ) et puis, si vous voulez être sûr que vous vérifiez qu'il est arguments de ligne de commande et le temps qu'il a été lancé (par exemple, "shutdown-h +240" a commencé à 14:51 arrêté à 18:51).
Dans le cas général, il n'y a du point de vue de l'ensemble du système il n'existe aucun moyen pour ce faire. Il y a beaucoup de manières différentes d'un "shutdown" qui peut arriver. Par exemple, une personne peut décider de retirer la fiche de pour dur d'arrêter un programme que maintenant il a une mauvaise/les comportements dangereux au temps d'arrêt ou un ONDULEUR pourrait envoyer un signal SIGHUP et puis tout simplement l'échec. Étant donné qu'un tel arrêt peut se produire soudainement et sans avertissement n'importe où dans un système il n'y a aucun moyen d'être sûr qu'il est normal de continuer à courir après un signal SIGHUP.
Si un processus reçoit un signal SIGHUP vous devriez fondamentalement supposer que quelque chose de plus méchant suivront bientôt. Si vous voulez faire quelque chose de spécial et partiellement ignorer SIGHUP alors a) vous avez besoin de coordonner avec ce programme va faire l'arrêt et b), vous devez être prêt que si un autre système à l'arrêt et vous tue mort peu de temps après une SIGHUP votre logiciel et vos données de survivre. Écrire toutes les données que vous avez et seulement continuer à écrire à ajouter seulement les fichiers sûrs, les mises à jour atomiques.
Pour votre cas, je suis presque sûr de votre solution actuelle (traiter tous les SIGHUPs qu'un arrêt) est la bonne façon de procéder. Si vous voulez améliorer les choses, vous devriez probablement ajouter une fonctionnalité à l'arrêt du programme qui fait notifier par DBUS ou quelque chose de similaire.