Der beste Weg, um einen Abschalthaken zu machen?

9

Da Ubuntu seit einiger Zeit auf Upstart angewiesen ist, möchte ich einen Upstart-Job verwenden, um bestimmte Anwendungen beim Herunterfahren oder Neustarten des Systems ordnungsgemäß herunterzufahren. Es ist wichtig, dass das Herunterfahren oder Neustarten des Systems blockiert wird, bis diese Anwendungen heruntergefahren werden.

Die Anwendungen werden gelegentlich manuell gestartet, und beim Herunterfahren des Systems sollte automatisch ein Skript beendet werden (das ich bereits habe). Da die Anwendungen nicht zuverlässig beendet werden können, ohne dass (fast alle) anderen Dienste ausgeführt werden, muss das Beenden der Anwendungen erfolgen, bevor der Rest des Herunterfahrens beginnt.

Ich denke, ich kann dies durch einen Startjob lösen, der beim Herunterfahren ausgelöst wird, aber ich bin mir nicht sicher, welche Ereignisse ich auf welche Weise verwenden soll. Bisher habe ich folgende (teilweise widersprüchliche) Aussagen gelesen:

  • Es gibt kein allgemeines Herunterfahren im Upstart
  • Verwenden Sie eine Zeilengruppe wie start on starting shutdownin der Jobdefinition
  • Verwenden Sie eine Zeilengruppe wie start on runlevel [06S]in der Jobdefinition
  • Verwenden Sie eine Zeilengruppe wie start on starting runlevel [06S]in der Jobdefinition
  • Verwenden Sie eine Zeilengruppe wie start on stopping runlevel [!06S]in der Jobdefinition

Aus diesen Empfehlungen ergeben sich folgende Fragen:

  • Gibt es ein allgemeines Shutdown-Ereignis in Ubuntus Upstart oder nicht?
  • Was ist der empfohlene Weg, um einen "Shutdown Hook" zu implementieren?
  • Wann werden die Ereignisse Runlevel [x] ausgelöst? Ist dies beim Betreten des Runlevels oder beim Betreten des Runlevels?
  • Können wir so etwas wie start on starting runlevel [x]oder verwenden start on stopping runlevel [x]?
  • Was wäre die beste Lösung für mein Problem?

Vielen Dank

Binarus
quelle

Antworten:

2

startingund runlevelsind separate Ereignisse, so dass Sie nicht sinnvoll sagen können starting runlevel N.

Das runlevel NEreignis wird zu Beginn des Eintritts in das Runlevel ausgegeben. Wenn Sie start on runlevel Ndann Ihre Aufgabe bei der Eingabe ausgeführt. Die Ausführung erfolgt, wenn der Einstieg in das Runlevel abgeschlossen ist run on started rc RUNLEVEL=N.

So wie ich es verstehe, müssen Sie start on runlevel [06S]tun, was Sie wollen; Es sollte theoretisch laufen, bevor etwas anderes gestoppt wird. Für eine genauere Steuerung können Sie verwenden, start on stopping apache or stopping mysql or ...damit Ihre Aufgabe ausgeführt wird, bevor eine von ihnen heruntergefahren werden darf.


Bearbeitet, um Runlevel 5 in S zu ändern.

Geekosaurier
quelle
1
Der einzige Grund für das besondere startupEreignis ist, dass etwas zum "Ansaugen der Pumpe" erforderlich ist. Nachdem dieses eine privilegierte Ereignis gesendet wurde, kann und wird alles andere durch die Jobs und Aufgaben definiert, die von ausgelöst werden startup. Da es kein einziges shutdownEreignis gibt, gibt es zu viele verschiedene Arten, shutdownals dass dies sinnvoll wäre. Es ist besser, sich direkt auf die Jobs zu verlassen, die ausgeführt werden müssen.
Geekosaurier
Vielen Dank. Ich nehme Ihre Antwort dankbar an, da sie meine Fragen beantwortet und das Problem löst. Trotzdem habe ich eine zusätzliche Frage / einen Kommentar (der jedoch nicht mit einem Problem zusammenhängt): AFAIK, es ist das Ziel des Emporkömmlings, das Runlevel-Konzept vollständig zu ersetzen. Die Tatsache, dass wir uns auf Runlevel verlassen müssen, um einen globalen Shutdown-Hook zu erhalten, widerspricht diesem Ziel. Ich denke, Emporkömmling muss eine solche Veranstaltung einführen. Ich verstehe klar, dass es besser wäre, sich auf die Jobs zu verlassen, die wir wirklich brauchen, aber andererseits ist es in meinem Fall eine ganze Reihe von Jobs ... Fortsetzung ...
Binarus
(fast alles, was läuft), und ich wage es nicht einmal, die Beziehung zwischen den auf der Box ausgeführten Prozessen (ps -Alf) und den Jobs herauszufinden, die diese Prozesse steuern. Natürlich gibt es keine 1: 1-Beziehung. Es gibt Jobs, die sich nicht auf Prozesse beziehen (z. B. das Netzwerk konfigurieren), und ich nehme an, es gibt genügend Prozesse, die sich sowieso nicht auf Jobs beziehen, insbesondere wenn man Dinge manuell startet.
Oli
Upstart ersetzte fest codierte Runlevel; Soweit ich feststellen kann, verschwindet das Runlevel- Konzept nicht, es wird jetzt nur im Userspace definiert. Wenn Sie sich über einen so langen Zeitraum Sorgen machen, möchten Sie meinen letzten Vorschlag verwenden, on stopping servicea or stoping serviceb or ...für alle Dienste, die Sie ausführen müssen, weiterzumachen.
Geekosaurier
-1 für mehrere Ungenauigkeiten. Auf jeden Fall wird dies nicht wirklich funktionieren. Stopp auf gestartetem rc RUNLEVEL = ist kein anderer frun 'Stopp auf Runlevel [016]. Dies liegt daran, dass keines der beiden Ereignisse das Herunterfahren blockiert. Es gibt auch eine ungültige Syntax, da 'run on' nicht gültig ist. Alles in allem verwirrt dies das Problem nur, es hilft eigentlich nicht. Entschuldigung, dass dies so spät ist! Ich überprüfe nur alte Antworten.
SpamapS
2

Um zu verhindern, dass das Herunterfahren fortgesetzt wird, während Ihr Job beendet wird, sollten Sie Folgendes verwenden:

stop on starting rc RUNLEVEL=[016]

Dies funktioniert, da als erstes, wenn Sie 'shutdown' eingeben, Tunlevel 0 ausgegeben wird. rc startet auf Runlevel und der Übergang von gestoppt -> Start wird vollständig blockiert, bis alle Jobs, die ebenfalls den Status ändern müssen, diesen Status abschließen.

Sie sollten sicherstellen, dass Ihr Prozess schnell auf SIGTERM reagiert. Wenn es nicht innerhalb von 5 Sekunden antwortet, sendet Upstart es SIGKILL. Sie können dies mit 'Kill Timeout X' erhöhen.

Die 1 dort ist übrigens etwas knifflig. Sie müssen sicherstellen, dass Ihr Start etwas enthält, das zu diesem Zeitpunkt auf Runlevel [2345] beginnt, damit ein Benutzer, der für die Wartung im Einzelbenutzermodus ausfällt, seinen Job erneut startet. Glücklicherweise wurde viel Arbeit investiert, um dies zum vorgeschlagenen üblichen Start zu machen

start on runlevel [2345]

In einigen Fällen benötigen Sie auch etwas, das so lange läuft, bis das Netzwerk heruntergefahren ist (z. B. dbus / network-manager). Dafür willst du

stop on deconfiguring-networking

Dies ist ein Ereignis, das später beim Herunterfahren ausgegeben wird und das ebenfalls blockiert wird, bis alle Jobs, die es verwenden, ihre Statusübergänge vollständig abgeschlossen haben.

SpamapS
quelle
Meinten Sie, start on starting ... es macht nicht viel Sinn, wenn mein Abschalthaken an irgendetwas anhält. start on starting rc RUNLEVEL=[016]würde viel mehr Sinn machen. Und vielleicht wird ein taskhineingeworfen, um sicherzustellen, dass es abgeschlossen werden kann, bevor andere Dinge laufen.
Tejay Cardon
0

Geekosaurier, vielen Dank für Ihre Hilfe.

In der Zwischenzeit habe ich die start on runlevel [016]Methode ausprobiert , aber sie hat nicht funktioniert, und ich glaube, ich verstehe warum:

Der Job wurde zwar gestartet, aber das Herunterfahren wurde erst blockiert, nachdem die Aufgabe des Jobs abgeschlossen wurde. Ich bin mir jetzt ziemlich sicher, dass die Ereignisse startingund stoppingdie einzigen Ereignisse sind, die in einer Jobdefinition verwendet werden können, um andere Jobs zu blockieren, und ich denke, dass dies in den Handbüchern von Upstart versucht wird, uns zu sagen. Daher führt die Verwendung des Runlevel-Ereignisses niemals zum Blockieren anderer Jobs oder zum Herunterfahren. daher ist es für meinen Zweck nutzlos.

Stattdessen habe ich zwei Möglichkeiten:

  1. Finden Sie nach einem Ihrer Vorschläge alle Jobs heraus, die die jeweiligen Anwendungen benötigen, und fügen Sie alle in das Startereignis für das folgende Skript ein:

    start on stopping job1 or stopping job2 or ...
    

    Dies ist so viel Arbeit, dass ich ernsthaft darüber nachdenke, die Jobliste zu sichern und durch sed zu führen, um automatisch eine Startzeilengruppe für meinen Job zu erstellen, die alle Jobs enthält, die normalerweise auf dem System ausgeführt werden.

    Der Vorteil wäre, dass die jeweiligen Anwendungen selbst dann heruntergefahren würden, wenn jemand eine der Voraussetzungen manuell stoppt (im Gegensatz zum Stoppen durch Runlevel-Änderung / Herunterfahren / Neustart).

  2. Suchen Sie den einen Job, der beim Neustart / Herunterfahren des Systems zuerst gestoppt wird (nennen wir diesen Job "FirstJob"), und verwenden Sie diesen Job in einer Zeilengruppe wie:

    start on stopping FirstJob
    

    Die Hauptnachteile wären, dass ich nicht weiß, ob ein solcher Job überhaupt existiert und ob dieser Job wirklich von allen anderen Jobs abhängt, von denen die jeweilige Anwendung tatsächlich abhängt ("hängt von einem anderen Job ab" bedeutet in diesem Fall "wird gestoppt" vollständig bevor andere Jobs zu stoppen beginnen ").

Ich bin mir nicht sicher, welche der beiden Möglichkeiten die bessere ist ...

Binarus
quelle
Ich würde das sedDrehbuch gleich machen, wenn ich in deinen Schuhen stecke.
Geekosaurier