2014-01-09 11 views
6

Ich habe ein seltsames Problem in Bezug auf das Senden von Signal 9 (SIGKILL) an den Init-Prozess (PID 1). Wie Sie vielleicht wissen, kann SIGKILL nicht über Signalhandler ignoriert werden. Als ich versuchte, SIGKILL an init zu senden, bemerkte ich, dass nichts passierte; init würde nicht beendet werden. Als ich versuchte, dieses Verhalten herauszufinden, entschied ich mich, mich an den init-Prozess mit strace zu heften, um klarer zu sehen, was vor sich ging. Jetzt kommt der komische Teil. Wenn ich den init-Prozess mit strace "schaue" und SIGKILL sende, stürzt das System ab.SIGKILL Init-Prozess (PID 1)

Meine Frage ist, warum passiert das? Warum stürzt das System ab, wenn ich den Prozess betrachte und warum stürzt es nicht ab, wenn ich es nicht bin? Wie gesagt, in beiden Fällen sende ich SIGKILL an init. Getestet auf CentOS 6.5, Debian 7 und Arch.

Danke!

+0

Ohne 'init', ich glaube nicht, dass Sie ein funktionierendes Betriebssystem haben. Wenn Sie 'init' beenden wollen, können Sie genauso gut shutdown/halt/poweroff ausführen. – janos

+1

Ja, du hast recht, aber mein "Experiment" war aus purer Neugierde. – Alex

+0

Sie haben Recht, es macht Spaß. – janos

Antwort

6

Der Linux-Kernel erzwingt absichtlich einen Systemabsturz, wenn init endet (siehe http://lxr.free-electrons.com/source/kernel/exit.c?v=3.12#L501 und insbesondere der Aufruf an panic darin). Daher als Schutz, wird der Kernel liefert nicht jeden fatales Signal an init und SIGKILL ist nicht ausgenommen (siehe http://lxr.free-electrons.com/ident?v=3.12&i=SIGNAL_UNKILLABLE) (jedoch ist der Code Fluss gewunden genug, dass ich nicht sicher bin, aber ich Verdächtiger eines Kernel-generierte SIGSEGV oder ähnliches würde durchlaufen).

Die Anwendung ptrace(2) (der Systemaufruf, den strace verwendet), um 1 zu verarbeiten, deaktiviert anscheinend diesen Schutz. Dies könnte als ein Fehler im Kernel bezeichnet werden. Ich bin nicht sehr geschickt darin, den Code zu durchsuchen, um diesen Fehler zu finden.

Ich weiß nicht, ob andere Unix-Varianten die gleiche Crash-on-Exit-Semantik oder Signalschutz auf init anwenden. Es wäre vernünftig, wenn das Betriebssystem ein sauberes Herunterfahren oder einen Neustart statt einer Panik ausführt, wenn init terminiert (zumindest wenn es dies tut, indem es _exit aufruft), aber soweit ich weiß, haben alle modernen Unix-Varianten ein dediziertes System Rufen Sie stattdessen an, um dies anzufordern (reboot(2)).

+0

Vielen Dank für Ihre Erklärung! – Alex

+0

BTW, unter Debian 7 stürzt SIGSEGV die init nicht ab. Auf Arch und CentOS tut es das. – Alex

+1

Ich fürchte, "Debian 7", "Arch" und "CentOS" beziehen sich alle auf so große Bündel verschiedener Software mit unsicherem Alter, dass dies als Datenpunkt nutzlos ist. Wenn Sie auch 'kill -SEGV 1' versucht haben, sagt Ihnen das nichts darüber, was für * kernelgenerierten * SIGSEGV passiert, z. wenn 'init' tatsächlich versucht, einen ungültigen Zeiger zu dereferenzieren. – zwol