thanks heaps Simon... tel :+61402350315
Rajneesh N. Shetty
 
      From: Mages Simon <mages.si...@googlemail.com>
 To: tech@openbsd.org 
 Sent: Monday, 23 March 2015, 2:54
 Subject: panic - init died
   
Hi there,

we got some Problems with init.

"init died (signal 11 exit 0)"

after using reboot(8) without any flags.

after some investigation i saw that in reboot(8)
at line 241 folling code starts:

    for (i = 1;; ++i) {
        if (kill(-1, SIGKILL) == -1) {
            if (errno == ESRCH)
                break;
            goto restart;
        }
        if (i > 5) {
            warnx("WARNING: some process(es) wouldn't die");
            break;
        }
        (void)sleep(2 * i);
    }

    reboot(howto);
    /* FALLTHROUGH */

Every process gets a SIGKILL and becomes a Zombie until
init calls wait(2) on every one of those. But a Zombie
doesn't respond to signals, so after the first iterration
the loop will just wait. After the loop reboot(2) is
called, if processes are still there or not.

In case every Zombie is finally dead everythings fine
because init is sleeping and the call to vfs_shutdown,
which frees all pages, doesn't affect init.

But if there are still zombies arround which init tries
to clean up und then reboot(2) is called and frees all
page then init gets a SIGSEGV. Init tries to handle it
but the signal handler for SIGSEGV is also freed allready.
If this happens init dies and the Kernel Panics because
of kern/kern_sig.c:
>"revision 1.167
>date: 2014/06/21 20:58:30;  author: guenther;  state: Exp;  lines: +12 -1;  
>comm
>itid: IvlsVYNsU5F7UWHE;
>If the kernel generates a deadly trap signal (SEGV, BUS, etc) for
>an untraced process but finds it blocking or ignoring it, just kill
>the process instead of looping.  It's undefined behavor in POSIX but
>quite annoying when encountered in practice."

A little stupid aproche to solve this would be:
Index: kern//kern_sig.c
===================================================================
RCS file: /home/cvs/src/sys/kern/kern_sig.c,v
retrieving revision 1.178
diff -u -p -r1.178 kern_sig.c
--- kern//kern_sig.c    9 Feb 2015 13:41:24 -0000    1.178
+++ kern//kern_sig.c    18 Mar 2015 11:38:07 -0000
@@ -769,10 +769,13 @@ trapsignal(struct proc *p, int signum, u
         * generated by the kernel, be ignorable or blockable.
         * If it is and we're not being traced, then just kill
         * the process.
+        *
+        * XXX: except we are init, init shouldn't die
         */
         if ((pr->ps_flags & PS_TRACED) == 0 &&
             (sigprop[signum] & SA_KILL) &&
-            ((p->p_sigmask & mask) || (ps->ps_sigignore & mask)))
+            ((p->p_sigmask & mask) || (ps->ps_sigignore & mask)) &&
+            p->p_pid != 1)
             sigexit(p, signum);
         ptsignal(p, signum, STHREAD);
     }

But from my point of view init should handle this completely
by him self. Because of init.c:
>"revision 1.45
>date: 2010/10/15 07:11:02;  author: dlg;  state: Exp;  lines: +4 -4;
>freebsd uses SIGINT to request a reboot, we may as well be consistent."

I thought about fixing reboot(8) in a way that it just sends
SIGINT to init(8) but this feels a little bit wired because
there are still other cases which are only handled by reboot(8)
and init(8) is not aware of.

It would feel more natural if init(8) would handle all the cases.
Also the code redundancy in init(8) and reboot(8) seems to be not
a good idea.

But maybe there is a reason for it.

BR

Simon Mages



   

Reply via email to