Verwenden Sie systemd, um ein Skript vor dem Herunterfahren des Systems auszuführen?

7

Ich habe ein Skript geschrieben, das alle meine VirtualBox-Maschinen anhält und eine Zeile einfügt /etc/rc.local.shutdown, aber es scheint nicht zu funktionieren.

su - XX -c /XX

Wenn ich das nächste Mal boote, teilt mir VirtualBox mit, dass es sich um einen Computer handelt Aborted, sodass das Skript nicht ausgeführt wurde. (Das manuelle Starten dieses Skripts funktioniert bei mir.)

PS habe ich schon aktiviert shutdown.target

BEARBEITEN

Das Problem scheint komplizierter zu sein, als ich dachte. .bashrcWenn es ausgeführt wird tty3, wird es ausgeführt startx. Wenn das System sich also zum Herunterfahren / Neustarten entschließt, wird der VBoxSVCProzess und andere Dinge abgebrochen, wenn die X-Sitzung stirbt.

Ich habe auch versucht, den Quellcode von zu hacken xfsm-shutdown-helper, eine Fälschung zu machen systemctl, die mein Skript zuerst ausführt, keines der oben genannten funktioniert.

Gänseblümchen
quelle
Wie viele VMs fahren Sie aus Neugier gleichzeitig herunter? Ich habe nichts mit Ihrer Frage zu tun, aber ich glaube, ich habe in VirtualBox 4.2.6 ein Problem gefunden, bei dem das Herunterfahren von zu vielen gleichzeitig (5 bis 10) (alle sind verknüpfte Klone von einer gemeinsam genutzten VM) zu beschädigten geklonten VMs führt.
Adamrmcd
@adamrmcd Ich schalte eins nach dem anderen ...
Gänseblümchen
Möchten Sie die VMs anhalten, anstatt sie herunterzufahren? In einem klassischen (SysV?) Init-basierten System sollten Sie dies von inittab / aus tun können, indem Sie die Skripte für das zum Herunterfahren verwendete Runlevel ändern ... (Lesen Sie die Init-Manpage, es unterscheidet sich zwischen Unixen, möglicherweise zwischen Linux Verteilungen auch)
Gert van den Berg
Vielleicht möchten Sie auch eine Protokolldatei aus dem Skript wiedergeben, um sicherzugehen, dass sie tatsächlich nicht ausgeführt wurde und nicht nur aufgrund eines anderen Fehlers fehlgeschlagen ist ...
Gert van den Berg
1
Wenn ti Init-Skripte im SysV-Stil unterstützt, würden Sie ein solches Skript hinzufügen /etc/init.d/stopvms, um die VMs zu stoppen, wenn ein "stop" -Parameter übergeben wird. Anschließend erstellen Sie Links (symbolisch oder hart) zu diesem Skript, z. B. /etc/rc5.d/K01stopvmsund /etc/rc3.s/K01stopvms. (Die Skripte in den Verzeichnissen werden in der richtigen Reihenfolge ausgeführt (K * beim Verlassen eines Runlevels, S * beim Eingeben eines Runlevels).) (Sie sollten dies auch als "Start" -Skripte in Runlevel 0 (Herunterfahren) und 6 (Neustart) ausführen können ))
Gert van den Berg

Antworten:

1

Wenn ich Sie richtig verstehe, möchten Sie Ihre VB-Computer anhalten, bevor Ihre Bash-Sitzung auf tty3 oder Ihr Xserver beendet wird.

Ich glaube, systemd ist sich Ihrer laufenden Xsession nicht bewusst, da Sie sie von Ihrem .bashrc aus starten. Daher ist es schwierig, systemd anzuweisen, Ihre VBs auszusetzen, bevor Ihre Shell oder Ihre Xsession beendet wird. Sie müssen einen Platz in der Abschaltsequenz finden, der "früh genug" ist, was schwierig zu finden und semantisch fragwürdig sein könnte, da er "Benutzermaterial" mit "Systemmaterial" mischen würde.

Die Lösungen können etwas davon abhängen, wie systemd Ihre Prozesse beendet, aber Folgendes sollte zumindest in eine gute Richtung weisen:

Bevor die Shell endet

suspendVB() {
        echo "suspending VBs"
        # put real code here
        exit
}

trap suspendVB EXIT

Wenn Sie dies zur RC-Datei Ihrer Bash machen (oder zu .bashrc hinzufügen), wird der Code in suspendVB()ausgeführt, bevor die Shell beendet wird. Sie können dies testen, indem Sie ausführen

bash --rcfile xxx

wo die Datei xxxden Code von oben enthält. Dadurch wird eine weitere Shell in Ihrer aktuellen Shell gestartet, nur zum Testen. Wenn Sie dann einen einfachen Exit ausführen, sehen Sie:

martin@beaureve:~$ exit
exit
suspending VBs
/home/martin >

und Sie sind wieder in Ihrer ursprünglichen (Login-) Shell.

Möglicherweise müssen Sie herausfinden, wie systemd Ihre Login-Shells tatsächlich beendet, und Sie müssen möglicherweise EXITdurch andere Signale ersetzen . Suchen Sie den trapBefehl, um mehr zu erfahren.

Beachten Sie, dass wenn systemd Ihre Prozesse mit "-9" (SIGKILL) beendet, Sie die Beendigung nicht abfangen können, dh Sie haben kein Glück.

Bevor die Xsession endet

Alternativ können Sie mit Ihrer Xsession etwas Ähnliches versuchen. Dies ist in Fällen wichtig, in denen systemd Ihre Xsession beendet, bevor es Ihre Shells beendet. Möglicherweise möchten Sie einen Trap in eine der X-Startdateien einfügen (z. B. .xinitrc). Suchen Sie in den Manpages nach startxund xiniterfahren Sie mehr.

Wenn Ihre startxDatei ungefähr so ​​aussieht wie meine, wird der xserver im Vordergrund gestartet und Sie können alternativ einfach Ihre Suspend-Befehle nach der Zeile platzieren, in der X tatsächlich gestartet wurde (und überhaupt keine Traps verwenden):

xinit "$client" $clientargs -- "$server" $display $serverargs
retval=$?
echo " --- suspending VBs ---"

Ich habe die Zeile "Suspendieren von VBs" startx -- vt8eingefügt und wenn ich sie ausführe , wird auf vt8 eine Fullblows (kde) -Sitzung angezeigt. Erst wenn ich mich abmelde, wird die Zeile "Suspendieren von VBs" auf dem Bildschirm angezeigt.

Martin Drautzburg
quelle