Étant donné qu'Ubuntu s'appuie sur upstart depuis un certain temps déjà, j'aimerais utiliser un travail upstart pour arrêter en douceur 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'à ce que ces applications soient arrêtées.
Les applications seront lancées manuellement à l'occasion, et à l'arrêt du système, elles devraient être automatiquement terminées par un script (que j'ai déjà). Étant donné que les applications ne peuvent pas être terminées de manière fiable sans (presque tous) les autres services en cours d'exécution, vous devez mettre fin à ces applications avant le début du reste de l'arrêt.
Je pense que je peux résoudre ce problème par un travail rapide qui sera déclenché à l’arrêt, mais je ne suis pas sûr des événements que je devrais utiliser de quelle manière. Jusqu'à présent, j'ai lu les déclarations suivantes (partiellement contradictoires):
start on starting shutdown
dans la définition de travailstart on runlevel [06S]
dans la définition de travailstart on starting runlevel [06S]
dans la définition de travailstart on stopping runlevel [!06S]
dans la définition de travailDe ces recommandations, les questions suivantes se posent:
start on starting runlevel [x]
ou start on stopping runlevel [x]
?Merci beaucoup
starting
et runlevel
sont des événements distincts. Vous ne pouvez donc pas dire de manière significative starting runlevel N
.
L'événement runlevel N
est émis au début de l'entrée dans le niveau d'exécution. Si vous start on runlevel N
, votre tâche est exécutée à l'entrée. La méthode à 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 théorie fonctionner avant que tout soit arrêté. Pour un contrôle plus précis, vous pouvez utiliser start on stopping Apache or stopping mysql or ...
afin que votre tâche soit exécutée avant qu'un quelconque d'entre eux ne soit autorisé à être arrêté.
Édité pour changer le niveau d'exécution 5 en S.
Afin d'empêcher l'arrêt de continuer pendant que votre travail s'arrête, vous voudrez utiliser ceci:
stop on starting rc RUNLEVEL=[016]
Cela fonctionnera parce que la première chose qui se passe lorsque vous tapez "shutdown" est tunlevel 0 est émis. La commande rc démarre au niveau d'exécution et la transition entre l'arrêt -> le démarrage se bloque 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, Upstart l'enverra à SIGKILL. Vous pouvez en parler avec 'kill timeout X'.
Le 1 dans, btw est un peu délicat, vous devez vous assurer que votre démarrage comprend quelque chose qui commence au niveau d'exécution [2345] à ce moment-là, de sorte qu'un utilisateur qui passe pour une maintenance en mode mono-utilisateur puisse reprendre son travail. Heureusement, beaucoup de travail a été fait pour que ce soit le début habituel suggéré.
start on runlevel [2345]
De plus, dans certains cas, vous avez besoin de quelque chose pour continuer à fonctionner jusqu’à ce que le réseau soit coupé (tel que dbus/network-manager). Pour ça tu veux
stop on deconfiguring-networking
Il s’agit d’un événement émis plus tard au cours de l’arrêt qui sera également bloqué jusqu’à ce que tous les travaux qui l’utilisent achèvent leurs transitions dans l’état.
Geekosaur, merci beaucoup pour votre aide.
Entre-temps, j'ai essayé la méthode start on runlevel [016]
, mais cela n'a pas fonctionné et je pense comprendre pourquoi:
Le travail a bien été démarré, mais le processus d'arrêt n'a pas été bloqué jusqu'à ce que la tâche du travail soit terminée. Je suis bien sûr maintenant que les événements starting
et stopping
sont les seuls événements pouvant être utilisés dans une définition de travail pour bloquer d'autres travaux, et je pense que c'est ce que les manuels de Upstart tentent de nous dire. Par conséquent, l'utilisation de l'événement runlevel n'entraînera jamais le blocage d'autres travaux ou du processus d'arrêt; ainsi, il est inutile pour mon but.
Au lieu de cela, il me semble avoir deux possibilités:
En suivant l'une de vos propositions, recherchez tous les travaux nécessaires aux applications respectives 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 songe sérieusement à vider la liste des tâches et à la parcourir pour générer automatiquement une strophe de début pour mon travail, qui comprend tous les tâches en cours d’exécution sur le système.
L'avantage serait que les applications respectives seraient fermées même lorsque quelqu'un arrêtait manuellement l'un des prérequis (au lieu de les arrêter par un changement de niveau d'exécution/un arrêt/un redémarrage).
Recherchez le travail qui sera arrêté en premier lieu lors du redémarrage/arrêt du système (appelons ce travail "FirstJob") et utilisez ce travail dans une strophe du type:
start on stopping FirstJob
Le principal désavantage serait que je ne sache pas si un tel travail existe et si ce travail dépend vraiment de tous autres travaux dont l’application dépend réellement ("dépend d’un autre emploi" dans ce cas signifie "sera complètement arrêté avant qu'un autre travail ne commence à s'arrêter").
Je ne sais pas laquelle des deux possibilités est la meilleure ...