Bug 12071 - Busybox reboot command not working in version 1.29.3
Summary: Busybox reboot command not working in version 1.29.3
Status: NEW
Alias: None
Product: Busybox
Classification: Unclassified
Component: Other (show other bugs)
Version: 1.29.x
Hardware: Other Linux
: P5 blocker
Target Milestone: ---
Assignee: unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-07-26 04:38 UTC by Krishna
Modified: 2019-12-11 06:10 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:


Attachments
Busybox configuration (32.54 KB, application/octet-stream)
2019-07-26 04:41 UTC, Krishna
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Krishna 2019-07-26 04:38:57 UTC
Dear Team,

Recently we have migrated to latest version 1.29.3 from 1.21.0. And we have aligned all new config value with respect to project requirement.

During unit testing we found that reboot command is not working as expected. 

We dig into source code and found that removal of "bb_siganls" api where SIGTERM handler get registered with "halt_reboot_pwoff".

Removed in latest version and it looks happened in 1.23.x version.

bb_signals(0
                                                + (1 << SIGUSR1) /* halt */
                                                + (1 << SIGTERM) /* reboot */
                                                + (1 << SIGUSR2) /* poweroff */
                                                , halt_reboot_pwoff);

Also seen, now signal SIGTERM is getting recorded and handled in check_delayed_sigs() function but somehow it is not working for us.

When reverted back the changes it started working.

Please do let us know the behind reason of removing the code and impact of this change.

Attached: config file
Comment 1 Krishna 2019-07-26 04:41:19 UTC
Created attachment 8181 [details]
Busybox configuration
Comment 2 Like Ma 2019-10-29 20:18:00 UTC
This issue may be similar to Bug 8521, which may be caused by 

https://git.busybox.net/busybox/commit/init/init.c?id=2bba9ad67a917de2624d427c8c107ce3e2d3d085

In addition, someone reported it in busybox github mirror:

https://github.com/mirror/busybox/commit/2bba9ad67a917de2624d427c8c107ce3e2d3d085
Comment 3 Denys Vlasenko 2019-11-01 15:08:51 UTC
Please let me know what happens with pid 1:

strace -s99 -p 1 

when you send it SIGTERM via "kill 1".
Comment 4 Krishna 2019-11-15 06:39:09 UTC
(In reply to Denys Vlasenko from comment #3)

Hi Denys,

Sorry for the late reply, Here is the response from device when executed signal SIGTERM.

root@Charter-WB:/# strace -s99 -p 1 &
root@Charter-WB:/# Process 1 attached - interrupt to quit
wait4(-1, kill 1
NULL, 0, NULL)                = ? ERESTARTSYS (To be restarted)
root@Charter-WB:/# --- SIGTERM (Terminated) @ 0 (0) ---
sigreturn()                             = ? (mask now [HUP INT QUIT TRAP PIPE])
kill(425, SIG_0)                        = 0

wait4(-1, busybox reboot
NULL, 0, NULL)                = ? ERESTARTSYS (To be restarted)
--- SIGTERM (Terminated) @ 0 (0) ---
sigreturn()                             = ? (mask now [HUP INT QUIT TRAP PIPE])
kill(425, SIG_0)                        = 0


root@Charter-WB:/# busybox reboot -f
Restarting system.
Kernel panic - not syncing: Software Reset
Rebooting in 2 seconds..

-Krishna
Comment 5 Denys Vlasenko 2019-11-17 16:33:16 UTC
We are here in this code:

                if (a->action_type & (SYSINIT | WAIT | ONCE | CTRLALTDEL | SHUTDOWN)) {
                        pid_t pid = run(a);
                        if (a->action_type & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN))
                                waitfor(pid);
                }

inside waitfor(pid), pid is 425:

        /* Wait for any child (prevent zombies from exiting orphaned processes)
         * but exit the loop only when specified one has exited. */
        while (1) {
                pid_t wpid = wait(NULL);
                mark_terminated(wpid);
                /* Unsafe. SIGTSTP handler might have wait'ed it already */
                /*if (wpid == pid) break;*/
                /* More reliable: */
                if (kill(pid, 0))
                        break;
        }

Evidently, you have one of SYSINIT, WAIT, CTRLALTDEL or SHUTDOWN processes which did not finish. init will wait for SYSINIT processes to finish before reacting to signals (including shutdown / reboot).

Can you look with "ps" which process is that?
Comment 6 Krishna 2019-11-27 05:56:51 UTC
(In reply to Denys Vlasenko from comment #5)

Thank you for the update.

It looks the ps id belongs to rcS.

root@Charter-WB:/# strace -s99 -p 1 &
root@Charter-WB:/# Process 1 attached - interrupt to quit
wait4(-1, busybox reboot
NULL, 0, NULL)                = ? ERESTARTSYS (To be restarted)
--- SIGTERM (Terminated) @ 0 (0) ---
root@Charter-WB:/# sigreturn()                             = ? (mask now [HUP INT QUIT TRAP PIPE])
kill(426, SIG_0)                        = 0
wait4(-1, ps -el |grep 426
0 S     0   426     1  0  80   0 -   515 runque ?        00:00:00 rcS
0 S     0   675   426  0  80   0 -   514 runque ?        00:00:00 S95init_user
root@Charter-WB:/# busybox reboot -f
Restarting system.
Kernel panic - not syncing: Software Reset
Rebooting in 2 seconds..

And I did the following patch to work reboot command.

--- ./init/init.c.orig	2019-07-25 17:30:58.000000000 +0530
+++ ./init/init.c	2019-07-25 17:35:48.000000000 +0530
@@ -1009,7 +1009,6 @@
 #endif
 		    + (1 << SIGUSR1)
 		    + (1 << SIGUSR2)
-		    + (1 << SIGTERM)
 		)) {
 			halt_reboot_pwoff(sig);
 		}
@@ -1163,6 +1162,10 @@
 	/* Set up signal handlers */
 	if (!DEBUG_INIT) {
 		struct sigaction sa;
+		
+		bb_signals(0
+		+ (1 << SIGTERM) /* reboot */
+		, halt_reboot_pwoff);
 
 		/* Stop handler must allow only SIGCONT inside itself */
 		memset(&sa, 0, sizeof(sa));
@@ -1188,7 +1191,6 @@
 			+ (1 << SIGPWR)  /* halt */
 #endif
 			+ (1 << SIGUSR1) /* halt */
-			+ (1 << SIGTERM) /* reboot */
 			+ (1 << SIGUSR2) /* poweroff */
 #if ENABLE_FEATURE_USE_INITTAB
 			+ (1 << SIGHUP)  /* reread /etc/inittab */
Comment 7 Denys Vlasenko 2019-11-28 10:54:58 UTC
(In reply to Krishna from comment #6)
> It looks the ps id belongs to rcS.

root@Charter-WB:/# strace -s99 -p 1 &
root@Charter-WB:/# Process 1 attached - interrupt to quit
wait4(-1, NULL, 0, NULL)                = ? ERESTARTSYS (To be restarted)
--- SIGTERM (Terminated) @ 0 (0) ---
root@Charter-WB:/# sigreturn()                             = ? (mask now [HUP INT QUIT TRAP PIPE])
kill(426, SIG_0)                        = 0
wait4(-1, 

> ps -el |grep 426
0 S     0   426     1  0  80   0 -   515 runque ?        00:00:00 rcS
0 S     0   675   426  0  80   0 -   514 runque ?        00:00:00 S95init_user


Well, this means that your sysinit process did not finish, and init still waits for it to finish.
This is by design: init thinks that attempt to shut down the system before sysinit has finished might not work correctly.

Make your rcS finish.

Specifically, what does S95init_user do?
Comment 8 Krishna 2019-12-11 06:10:00 UTC
(In reply to Denys Vlasenko from comment #7)

Thank you for the response. it's a script file used to launch rc.user