Kein SIGTERM vor SIGKILL/Shutdown mit systemd unter Ubuntu 16.04

Kein SIGTERM vor SIGKILL/Shutdown mit systemd unter Ubuntu 16.04

Ich bin auf dieses Problem gestoßen, als ich versuchte,Beantworten Sie eine Frage auf Stackoverflow.

Beim Herunterfahren sendet Ubuntu 12.04 SIGTERMan alle Prozesse und wartet höchstens 10 Sekunden, bevor es sie mit beendet SIGKILL(es sei denn, sie wurden vorher beendet). Meine Antwort auf SO enthält sogar ein Python-Skript, das dieses Verhalten überprüft. Das Skript wird in einem Terminal gestartet, in den Hintergrund gesendet und dann vom Terminal abgelehnt. Beim Empfang SIGTERMläuft das Skript einfach weiter und druckt kontinuierlich in eine Datei, wie lange es ausgeführt wurdenachEmpfangen SIGTERM.

Bei Ubuntu 16.04 wird das Skript jedoch beim Herunterfahren sofort beendet (es SIGTERMwird nichts protokolliert).

Ich habe eine Weile gegoogelt, aber nichts Nützliches gefunden. Ist noch nie jemand auf diese entscheidende Änderung für die aktuelle LTS-Version gestoßen?

Hier ist das Skriptsignaltest.py

import signal
import time

stopped = False

out = open('log.txt', 'w')

def stop(sig, frame):
    global stopped
    stopped = True
    out.write('caught SIGTERM\n')
    out.flush()

signal.signal(signal.SIGTERM, stop)

while not stopped:
    out.write('running\n')
    out.flush()
    time.sleep(1)

stop_time = time.time()
while True:
    out.write('%.4fs after stop\n' % (time.time() - stop_time))
    out.flush()
    time.sleep(0.1)

Das Skript verwendet die Datei log.txtim aktuellen Verzeichnis für alle Ausgaben. Es verfügt über eine Schleife, die jede Sekunde „running“ ausgibt. Der Empfang SIGTERMunterbricht die Schleife und startet eine weitere Schleife, die die seit dem Empfang vergangenen Sekunden ausgibt SIGTERM.

Das Skript wird von einem Terminal aus ausgeführt und zwar mit disown:

python signaltest.py &
disown

Nur um das klar zu stellen:Dies ist kein Duplikat vonUbuntu sendet beim Herunterfahren kein SIGTERM. Die Frage bezieht sich auf Desktop-Anwendungen und die Antworten passen auch nicht.

Antwort1

systemd (im Gegensatz zu upstart in früheren Ubuntu-Versionen) sendet zusätzlich SIGHUP beim Herunterfahren (und wartet 90 s statt 10 s, bevor es sendet SIGKILL). Ich schlage vor, es zu ignorieren oder auf die gleiche (idempotente) Weise SIGHUPzu handhaben .SIGTERMSIGHUP

Das modifizierte Testskript könnte wie folgt geändert werden:

import signal
import time

stopped = False

out = open('log.txt', 'w')

def stop(sig, frame):
    global stopped
    stopped = True
    out.write('caught SIGTERM\n')
    out.flush()

def ignore(sig, frsma):
    out.write('ignoring signal %d\n' % sig)
    out.flush()

signal.signal(signal.SIGTERM, stop)
signal.signal(signal.SIGHUP, ignore)

while not stopped:
    out.write('running\n')
    out.flush()
    time.sleep(1)

stop_time = time.time()
while True:
    out.write('%.4fs after stop\n' % (time.time() - stop_time))
    out.flush()
    time.sleep(0.1)

verwandte Informationen