----- Original Message ----- From: "Denys Vlasenko" <[EMAIL PROTECTED]> To: "Harald Kuethe" <[EMAIL PROTECTED]> Cc: <[email protected]> Sent: Friday, April 04, 2008 3:06 AM Subject: Re: [PATCH] init.c, halt command not working
> On Thursday 03 April 2008 23:33, Harald Kuethe wrote: >> > ----- Original Message ----- >> > From: "Denys Vlasenko" <[EMAIL PROTECTED]> >> > To: "Harald Kuethe" <[EMAIL PROTECTED]> >> > Cc: <[email protected]> >> > Sent: Wednesday, April 02, 2008 11:41 PM >> > Subject: Re: [PATCH] init.c, halt command not working >> >> ... >> >> > kill() returns 0 (success), so the system thinks that SIGTERM is delivered. >> > But init does not print your debug message. Very strange. >> > killall did the very same thing: "kill(1, SIGTERM)" and it worked... >> >> > Please try attached idagnostic patch. >> > It will spam your console if it will detect that init >> > has TERM blocked or set to unexpected handler. >> >> > Try to "kill 1" and "kill -USR1 1" and report what init says. >> > -- >> > vda >> >> This patch adds no additional output :-/ >> I put some more debugging output into the init_main function to find out >> where it hangs. >> It showed that init_main does not return from the run_actions(ASKFIRST); >> call, >> this explains that the additional diagnostics didn't come up. >> >> Following lines are copied from our inittab: >> ... >> ::askfirst:-/bin/sh >> vc/2::askfirst:-/bin/sh >> vc/3::askfirst:-/bin/sh >> ... >> >> It looks as if the init process is replaced by the shell without finishing >> generating the virtual consoles and waiting in the while loop >> because there are only 2 init processes here (there were some more (one for >> each vc) with the fork() instead of the vfork()) > > Huh. Soulds almost as if vfork() never returns in parent... ?! > Can you check? > > static pid_t run(const struct init_action *a) > { > pid_t pid; > sigset_t nmask, omask; > > /* Block sigchild while forking (why?) */ > sigemptyset(&nmask); > sigaddset(&nmask, SIGCHLD); > sigprocmask(SIG_BLOCK, &nmask, &omask); > pid = vfork(); > +bb_error_msg("vfork returned %d", (int)pid); > sigprocmask(SIG_SETMASK, &omask, NULL); > ... > > > and here: > > > static void run_actions(int action_type) > { > struct init_action *a, *tmp; > > for (a = init_action_list; a; a = tmp) { > tmp = a->next; > if (a->action_type == action_type) { > // Pointless: run() will error out if open of device > fails. > ///* a->terminal of "" means "init's console" */ > //if (a->terminal[0] && access(a->terminal, R_OK | > W_OK)) { > // //message(L_LOG | L_CONSOLE, "Device %s cannot > be opened in RW mode", a->terminal /*, strerror(errno)*/); > // delete_init_action(a); > //} else > if (a->action_type & (SYSINIT | WAIT | CTRLALTDEL | > SHUTDOWN | RESTART)) { > +bb_error_msg("before waitfor(run(a))"); > waitfor(run(a)); > +bb_error_msg("after waitfor(run(a))"); > delete_init_action(a); > } else if (a->action_type & ONCE) { > +bb_error_msg("before run(a)"); > run(a); > +bb_error_msg("after run(a)"); > delete_init_action(a); > } else if (a->action_type & (RESPAWN | ASKFIRST)) { > /* Only run stuff with pid==0. If they have > * a pid, that means it is still running */ > if (a->pid == 0) { > +bb_error_msg("before a->pid = run(a)"); > a->pid = run(a); > +bb_error_msg("after a->pid = run(a)"); > } > } > > > and here: > > static void waitfor(pid_t pid) > { > /* waitfor(run(x)): protect against failed fork inside run() */ > if (pid <= 0) > return; > +bb_error_msg("waiting for %d", (int)pid); > /* Wait for any child (prevent zombies from exiting orphaned processes) > * but exit the loop only when specified one has exited. */ > while (wait(NULL) != pid) > continue; > } > > > -- > vda Ok, here's the result: The first part is with a vfork() call in static pid_t run(const struct init_action *a) the second part uses fork() Freeing unused kernel memory: 68k init *Start init_main init: waiting for 10 *console_init init started init started: BusyBox v1.10.0 (2008-04-01 22:01:03 CEST) *single? *run_actions init: before waitfor(run(a)) init: run vfork returned 0 init: run vfork returned 11 *call bb_signals init: waiting for 11 ... init: after waitfor(run(a)) *signals *RESPAWN *ASKFIRST init: before a->pid = run(a) init: run vfork returned 0 Please press Enter to activate this console. init: run vfork returned 80 *call bb_signals init: after a->pid = run(a) init: before a->pid = run(a) init: run vfork returned 0 BusyBox v1.10.0 (2008-04-01 22:01:03 CEST) built-in shell (ash) Enter 'help' for a list of built-in commands. / # / # / # ps -ef PID USER VSZ STAT COMMAND 1 root 0 D init 2 root 0 S [keventd] 3 root 0 S [ksoftirqd_CPU0] 4 root 0 S [kswapd] 5 root 0 S [bdflush] 6 root 0 S [kupdated] 7 root 0 S [cifsoplockd] 8 root 0 S [mtdblockd] 9 root 0 S [rpciod] 21 root 0 S inetd 56 root 0 S [avia_av_wdt] 60 root 0 S [avia_gt_wdt] 80 root 0 S -/bin/sh 81 root 0 S init 83 root 0 R ps -ef / # / # kill 1 / # kill -SIGUSR1 1 / # halt / # killall init *HK: halt_reboot_pwoff init: before waitfor(run(a)) init: run vfork returned 0 init: run vfork returned 86 *call bb_signals init: waiting for 86 init: after waitfor(run(a)) The system is going down NOW! init: waiting for 95 Sending SIGTERM to all processes Sending SIGKILL to all processes Requesting system reboot *************************************************************** with fork() instead of vfork() Freeing unused kernel memory: 68k init *Start init_main init: waiting for 10 *console_init *init started init started: BusyBox v1.10.0 (2008-04-01 22:01:03 CEST) *single? run_actions init: before waitfor(run(a)) init: run fork returned 11 *call bb_signals init: waiting for 11 init: run fork returned 0 ... init: after waitfor(run(a)) *signals *RESPAWN *ASKFIRST init: before a->pid = run(a) init: run fork returned 80 *call bb_signals init: after a->pid = run(a) init: before a->pid = run(a) init: run fork returned 81 init: run fork returned 0 Please press Enter to activate this console. init: run fork returned 0 call bb_signals init: after a->pid = run(a) init: before a->pid = run(a) init: run fork returned 82 BusyBox v1.10.0 (2008-04-01 22:01:03 CEST) built-in shell (ash) Enter 'help' for a list of built-in commands. init: run fork returned 0 *call bb_signals init: after a->pid = run(a) init: before a->pid = run(a) init: run fork returned 0 init: run fork returned 84 *call bb_signals init: after a->pid = run(a) init: before a->pid = run(a) init: run fork returned 85 init: run fork returned 0 *call bb_signals init: after a->pid = run(a) init: before a->pid = run(a) init: run fork returned 0 init: run fork returned 86 *call bb_signals init: after a->pid = run(a) *sleep(5) correct TERM handler: 0x1004144c TERM is not blocked TERM is not pending / # ps -ef PID USER VSZ STAT COMMAND 1 root 0 S init 2 root 0 S [keventd] 3 root 0 S [ksoftirqd_CPU0] 4 root 0 S [kswapd] 5 root 0 S [bdflush] 6 root 0 S [kupdated] 7 root 0 S [cifsoplockd] 8 root 0 S [mtdblockd] 9 root 0 S [rpciod] 21 root 0 S inetd 56 root 0 S [avia_av_wdt] 60 root 0 S [avia_gt_wdt] 80 root 0 S -/bin/sh 81 root 0 S init 82 root 0 S init 84 root 0 S init 85 root 0 S init 86 root 0 S init 87 root 0 R ps -ef / # / # / # halt *HK: halt_reboot_pwoff init: before waitfor(run(a)) init: run fork returned 89 init: run fork returned 0 *call bb_signals init: waiting for 89 init: after waitfor(run(a)) The system is going down NOW! init: waiting for 98 Sending SIGTERM to all processes Sending SIGKILL to all processes Requesting system halt System halted. *something => my debug printouts Thanks four your help Harald _______________________________________________ busybox mailing list [email protected] http://busybox.net/cgi-bin/mailman/listinfo/busybox
