La meilleure façon de faire un crochet d'arrêt?

9

Étant donné qu'Ubuntu s'appuie sur la mise à jour depuis un certain temps maintenant, je voudrais utiliser une tâche de mise à jour pour arrêter gracieusement certaines applications lors de l'arrêt ou du redémarrage du système. Il est essentiel que l'arrêt ou le redémarrage du système soit bloqué jusqu'à l'arrêt de ces applications.

Les applications seront démarrées manuellement à l'occasion, et à l'arrêt du système devraient être automatiquement terminées par un script (que j'ai déjà). Étant donné que les applications ne peuvent pas être fermées de manière fiable sans (presque tous) les autres services en cours d'exécution, la fermeture des applications doit être effectuée avant le début de la fermeture.

Je pense que je peux résoudre ce problème par un travail parvenu qui sera déclenché à l'arrêt, mais je ne sais pas quels événements je dois utiliser de quelle manière. Jusqu'à présent, j'ai lu les déclarations suivantes (en partie contradictoires):

  • Il n'y a pas d'événement d'arrêt général dans le démarrage
  • Utilisez une strophe comme start on starting shutdowndans la définition de poste
  • Utilisez une strophe comme start on runlevel [06S]dans la définition de poste
  • Utilisez une strophe comme start on starting runlevel [06S]dans la définition de poste
  • Utilisez une strophe comme start on stopping runlevel [!06S]dans la définition de poste

De ces recommandations, les questions suivantes se posent:

  • Y a-t-il ou n'y a-t-il pas un événement d'arrêt général dans le début d'Ubuntu?
  • Quelle est la méthode recommandée pour implémenter un «crochet d'arrêt»?
  • Quand les événements sont-ils déclenchés au niveau d'exécution [x]; est-ce lorsque vous êtes entré dans le niveau d'exécution ou lors de l'entrée dans le niveau d'exécution?
  • Pouvons-nous utiliser quelque chose comme start on starting runlevel [x]ou start on stopping runlevel [x]?
  • Quelle serait la meilleure solution à mon problème?

Merci beaucoup

Binarus
la source

Réponses:

2

startinget runlevelsont des événements distincts, vous ne pouvez donc pas le dire de manière significative starting runlevel N.

L' runlevel Névénement est émis au début de l'entrée dans le niveau d'exécution. Si vous start on runlevel Npuis votre tâche s'exécute à l'entrée. La façon de s'exécuter lorsque l'entrée au niveau d'exécution est terminée est run on started rc RUNLEVEL=N.

Si je comprends bien, vous avez besoin d'un start on runlevel [06S]pour faire ce que vous voulez; il devrait en principe s'exécuter avant que quoi que ce soit d'autre soit arrêté. Pour un contrôle plus fin, vous pouvez utiliser start on stopping apache or stopping mysql or ...pour que votre tâche s'exécute avant que l'un d'eux ne puisse être arrêté.


Modifié pour changer le niveau d'exécution 5 en S.

geekosaure
la source
1
De plus, la seule raison pour laquelle il y a un startupévénement distingué est que quelque chose est nécessaire pour "amorcer la pompe". Après l'envoi d'un événement privilégié, tout le reste peut être, et est, défini par les travaux et tâches déclenchés par startup. Quant au fait qu'il n'y ait pas un seul shutdownévénement, il y a trop de types différents shutdownpour que cela ait un sens. Mieux vaut dépendre directement des travaux que vous devez exécuter.
geekosaur
Merci beaucoup. J'accepte avec reconnaissance votre réponse car elle répond à mes questions et résout le problème. Néanmoins, j'ai une question / commentaire supplémentaire (qui n'est pas lié à un problème, cependant): AFAIK, c'est l'objectif de parvenu à remplacer complètement le concept de niveau d'exécution. Le fait que nous devons compter sur les niveaux d'exécution pour obtenir un point d'arrêt global contredit cet objectif. Je pense que le débutant devra introduire un tel événement. Je comprends clairement qu'il vaudrait mieux dépendre des emplois dont nous avons vraiment besoin, mais d'un autre côté, dans mon cas, c'est tout un tas d'emplois ... suite ...
Binarus
(presque tout ce qui est en cours d'exécution), et je n'ose même pas penser à trouver la relation entre les processus en cours d'exécution sur la box (ps -Alf) et les jobs qui contrôlent ces processus; c'est sûr qu'il n'y a pas de relation 1: 1. Il y a des travaux qui ne sont liés à aucun processus (configuration du réseau, par exemple), et je suppose qu'il y a suffisamment de processus qui ne sont pas liés aux travaux de toute façon et surtout lors du démarrage manuel.
Oli
Upstart a remplacé les niveaux d' exécution codés en dur ; pour autant que je sache, le concept de niveau d'exécution ne disparaît pas, il est juste défini dans l'espace utilisateur maintenant. Si vous êtes inquiet à long terme, vous souhaitez utiliser ma dernière suggestion de fonctionner on stopping servicea or stoping serviceb or ...pour tous les services dont vous avez besoin.
geekosaur
-1 pour plusieurs inexactitudes. À plat, cela ne fonctionnera pas réellement. stop on started rc RUNLEVEL = [016] n'est pas différent frun 'stop on runlevel [016]'. En effet, aucun événement n'empêchera l'arrêt de se poursuivre. Il existe également une syntaxe non valide, car «exécuter sur» n'est pas valide. Dans l'ensemble, cela confond simplement le problème, cela n'aide pas vraiment. Désolé que ce soit si tard! Juste revoir les anciennes réponses.
SpamapS
2

Afin d'arrêter l'arrêt de continuer pendant que votre travail s'arrête, vous voudrez utiliser ceci:

stop on starting rc RUNLEVEL=[016]

Cela fonctionnera car la première chose qui se produit lorsque vous tapez «shutdown» est que le niveau de tunel 0 est émis. rc démarre au niveau d'exécution, et la transition entre arrêt -> démarrage bloquera complètement jusqu'à ce que les travaux qui doivent également changer d'état terminent cet état.

Vous voudrez vous assurer que votre processus répond rapidement à SIGTERM. S'il ne répond pas dans les 5 secondes, le parvenu lui enverra SIGKILL. Vous pouvez augmenter cela avec 'kill timeout X'.

Le 1 là-dedans, btw est un peu délicat, vous devez vous assurer que votre démarrage inclut quelque chose qui commence au niveau d'exécution [2345] à ce moment-là, afin qu'un utilisateur descendant pour la maintenance en mode utilisateur unique redémarre son travail. Heureusement, beaucoup de travail a été fait pour en faire le début habituel suggéré

start on runlevel [2345]

Dans certains cas, vous avez également besoin de quelque chose pour continuer à fonctionner jusqu'à ce que le réseau soit arrêté (comme dbus / network-manager). Pour ça tu veux

stop on deconfiguring-networking

Il s'agit d'un événement émis plus tard lors de l'arrêt qui sera également bloqué jusqu'à ce que les travaux qui l'utilisent terminent complètement leurs transitions dans l'état.

SpamapS
la source
Vouliez-vous dire que start on starting ... cela n'a pas beaucoup de sens d'avoir mon crochet d'arrêt sur quoi que ce soit. start on starting rc RUNLEVEL=[016]aurait beaucoup plus de sens. Et peut-être un taskjeton là-bas pour s'assurer qu'il peut se terminer avant que d'autres choses ne fonctionnent.
Tejay Cardon
0

Geekosaur, merci beaucoup pour votre aide.

En attendant, j'ai essayé la start on runlevel [016]méthode, mais ça n'a pas marché, et je pense comprendre pourquoi:

Le travail a bien été démarré, mais le processus d'arrêt n'a pas été bloqué jusqu'à la fin de la tâche du travail. Je suis maintenant certain que les événements startinget stoppingsont les seuls événements qui peuvent être utilisés dans une définition de travail pour bloquer d'autres travaux, et je pense que c'est ce que les manuels d'Upstart essaient de nous dire. Par conséquent, l'utilisation de l'événement de niveau d'exécution ne conduira jamais au blocage d'autres travaux ou au processus d'arrêt; ainsi, il est inutile pour mon but.

Au lieu de cela, il me semble avoir deux possibilités:

  1. Suite à l'une de vos propositions, recherchez tous les emplois dont les applications respectives ont besoin et incluez-les tous dans l'événement de démarrage du script comme celui-ci:

    start on stopping job1 or stopping job2 or ...
    

    C'est tellement de travail que je pense sérieusement à vider la liste des tâches et à la parcourir à travers sed pour produire automatiquement une strophe de démarrage pour ma tâche qui inclut toutes les tâches qui s'exécutent normalement sur le système.

    L'avantage serait que les applications respectives seraient fermées même si quelqu'un arrête manuellement l'une des conditions préalables (au lieu de les arrêter par un changement / arrêt / redémarrage du niveau d'exécution).

  2. Trouvez le seul travail qui sera arrêté au début lors du redémarrage / arrêt du système (appelons ce travail "FirstJob") et utilisez ce travail dans une strophe comme:

    start on stopping FirstJob
    

    Les principaux inconvénients seraient que je ne sais pas du tout si un tel travail existe et si ce travail dépend vraiment de tous les autres emplois dont dépend l'application réelle ("dépend d'un autre travail" signifie dans ce cas "sera arrêté" complètement avant que l’autre travail ne s’arrête ").

Je ne sais pas laquelle des deux possibilités est la meilleure ...

Binarus
la source
Je ferais le sedscript en ce moment, si j'étais à votre place.
geekosaur