aboutsummaryrefslogtreecommitdiff
path: root/init
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-01-31 01:03:45 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-01-31 01:03:45 +0000
commit72c99af0b44e150a712891f6a3ea7d41827cfffe (patch)
treeefd1f29d140f906deca0e8816e6b50ff2e87a77f /init
parentcab28aa7de336b0a39ef43ce0eb035a2cab30d4d (diff)
downloadbusybox-w32-72c99af0b44e150a712891f6a3ea7d41827cfffe.tar.gz
busybox-w32-72c99af0b44e150a712891f6a3ea7d41827cfffe.tar.bz2
busybox-w32-72c99af0b44e150a712891f6a3ea7d41827cfffe.zip
init: major improvement in documentation and signal handling.
Lots of nasty, but hard to trip, races are fixed. text data bss dec hex filename 1038828 924 10932 1050684 10083c busybox_old 1038787 924 10932 1050643 100813 busybox_unstripped
Diffstat (limited to 'init')
-rw-r--r--init/init.c671
1 files changed, 374 insertions, 297 deletions
diff --git a/init/init.c b/init/init.c
index 6af6830e4..3a02ece4b 100644
--- a/init/init.c
+++ b/init/init.c
@@ -15,6 +15,7 @@
15#include <sys/reboot.h> 15#include <sys/reboot.h>
16#include <sys/resource.h> 16#include <sys/resource.h>
17 17
18
18/* Was a CONFIG_xxx option. A lot of people were building 19/* Was a CONFIG_xxx option. A lot of people were building
19 * not fully functional init by switching it on! */ 20 * not fully functional init by switching it on! */
20#define DEBUG_INIT 0 21#define DEBUG_INIT 0
@@ -22,22 +23,53 @@
22#define COMMAND_SIZE 256 23#define COMMAND_SIZE 256
23#define CONSOLE_NAME_SIZE 32 24#define CONSOLE_NAME_SIZE 32
24 25
26/* Default sysinit script. */
25#ifndef INIT_SCRIPT 27#ifndef INIT_SCRIPT
26#define INIT_SCRIPT "/etc/init.d/rcS" /* Default sysinit script. */ 28#define INIT_SCRIPT "/etc/init.d/rcS"
27#endif 29#endif
28 30
29/* Allowed init action types */ 31/* Each type of actions can appear many times. They will be
32 * handled in order. RESTART is an exception, only 1st is used.
33 */
34/* Start these actions first and wait for completion */
30#define SYSINIT 0x01 35#define SYSINIT 0x01
31#define RESPAWN 0x02 36/* Start these after SYSINIT and wait for completion */
32/* like respawn, but wait for <Enter> to be pressed on tty: */ 37#define WAIT 0x02
33#define ASKFIRST 0x04 38/* Start these after WAIT and *dont* wait for completion */
34#define WAIT 0x08 39#define ONCE 0x04
35#define ONCE 0x10 40/*
41 * NB: while SYSINIT/WAIT/ONCE are being processed,
42 * SIGHUP ("reread /etc/inittab") will be ignored.
43 * Rationale: it would be ambiguous whether SYSINIT/WAIT/ONCE
44 * need to be rerun or not.
45 */
46/* Start these after ONCE are started, restart on exit */
47#define RESPAWN 0x08
48/* Like RESPAWN, but wait for <Enter> to be pressed on tty */
49#define ASKFIRST 0x10
50/*
51 * Start these on SIGINT, and wait for completion.
52 * Then go back to respawning RESPAWN and ASKFIRST actions.
53 * NB: kernel sends SIGINT to us if Ctrl-Alt-Del was pressed.
54 */
36#define CTRLALTDEL 0x20 55#define CTRLALTDEL 0x20
56/*
57 * Start these before killing all processes in preparation for
58 * running RESTART actions or doing low-level halt/reboot/poweroff
59 * (initiated by SIGUSR1/SIGTERM/SIGUSR2).
60 * Wait for completion before proceeding.
61 */
37#define SHUTDOWN 0x40 62#define SHUTDOWN 0x40
63/*
64 * exec() on SIGQUIT. SHUTDOWN actions are started and waited for,
65 * then all processes are killed, then init exec's 1st RESTART action,
66 * replacing itself by it. If no RESTART action specified,
67 * SIGQUIT has no effect.
68 */
38#define RESTART 0x80 69#define RESTART 0x80
39 70
40/* Set up a linked list of init_actions, to be read from inittab */ 71
72/* A linked list of init_actions, to be read from inittab */
41struct init_action { 73struct init_action {
42 struct init_action *next; 74 struct init_action *next;
43 pid_t pid; 75 pid_t pid;
@@ -65,13 +97,6 @@ enum {
65 97
66static void halt_reboot_pwoff(int sig) NORETURN; 98static void halt_reboot_pwoff(int sig) NORETURN;
67 99
68static void loop_forever(void) NORETURN;
69static void loop_forever(void)
70{
71 while (1)
72 sleep(1);
73}
74
75/* Print a message to the specified device. 100/* Print a message to the specified device.
76 * "where" may be bitwise-or'd from L_LOG | L_CONSOLE 101 * "where" may be bitwise-or'd from L_LOG | L_CONSOLE
77 * NB: careful, we can be called after vfork! 102 * NB: careful, we can be called after vfork!
@@ -241,6 +266,7 @@ static void open_stdio_to_tty(const char* tty_name, int exit_on_failure)
241 /* empty tty_name means "use init's tty", else... */ 266 /* empty tty_name means "use init's tty", else... */
242 if (tty_name[0]) { 267 if (tty_name[0]) {
243 int fd; 268 int fd;
269
244 close(STDIN_FILENO); 270 close(STDIN_FILENO);
245 /* fd can be only < 0 or 0: */ 271 /* fd can be only < 0 or 0: */
246 fd = device_open(tty_name, O_RDWR); 272 fd = device_open(tty_name, O_RDWR);
@@ -252,7 +278,8 @@ static void open_stdio_to_tty(const char* tty_name, int exit_on_failure)
252 if (DEBUG_INIT) 278 if (DEBUG_INIT)
253 _exit(2); 279 _exit(2);
254 /* NB: we don't reach this if we were called after vfork. 280 /* NB: we don't reach this if we were called after vfork.
255 * Thus halt_reboot_pwoff() itself need not be vfork-safe. */ 281 * Thus halt_reboot_pwoff() itself needs not be vfork-safe.
282 */
256 halt_reboot_pwoff(SIGUSR1); /* halt the system */ 283 halt_reboot_pwoff(SIGUSR1); /* halt the system */
257 } 284 }
258 dup2(STDIN_FILENO, STDOUT_FILENO); 285 dup2(STDIN_FILENO, STDOUT_FILENO);
@@ -313,89 +340,37 @@ static void init_exec(const char *command)
313static pid_t run(const struct init_action *a) 340static pid_t run(const struct init_action *a)
314{ 341{
315 pid_t pid; 342 pid_t pid;
316 sigset_t nmask, omask;
317 343
318 /* Block sigchild while forking (why?) */
319 sigemptyset(&nmask);
320 sigaddset(&nmask, SIGCHLD);
321 sigprocmask(SIG_BLOCK, &nmask, &omask);
322 if (BB_MMU && (a->action_type & ASKFIRST)) 344 if (BB_MMU && (a->action_type & ASKFIRST))
323 pid = fork(); 345 pid = fork();
324 else 346 else
325 pid = vfork(); 347 pid = vfork();
326 sigprocmask(SIG_SETMASK, &omask, NULL);
327
328 if (pid < 0) 348 if (pid < 0)
329 message(L_LOG | L_CONSOLE, "can't fork"); 349 message(L_LOG | L_CONSOLE, "can't fork");
330 if (pid) 350 if (pid)
331 return pid; 351 return pid; /* Parent or error */
332 352
333 /* Child */ 353 /* Child */
334 354
335 /* Reset signal handlers that were set by the parent process */ 355 /* Reset signal handlers that were set by the parent process */
356//TODO: block signals across fork(), prevent them to affect child before
357//signals are reset?
336 bb_signals(0 358 bb_signals(0
337 + (1 << SIGUSR1) 359 + (1 << SIGUSR1)
338 + (1 << SIGUSR2) 360 + (1 << SIGUSR2)
339 + (1 << SIGINT)
340 + (1 << SIGTERM) 361 + (1 << SIGTERM)
341 + (1 << SIGHUP)
342 + (1 << SIGQUIT) 362 + (1 << SIGQUIT)
343 + (1 << SIGCONT) 363 + (1 << SIGINT)
344 + (1 << SIGSTOP) 364 + (1 << SIGHUP)
345 + (1 << SIGTSTP) 365 + (1 << SIGTSTP)
346 , SIG_DFL); 366 , SIG_DFL);
347 367
348 /* Create a new session and make ourself the process 368 /* Create a new session and make ourself the process group leader */
349 * group leader */
350 setsid(); 369 setsid();
351 370
352 /* Open the new terminal device */ 371 /* Open the new terminal device */
353 open_stdio_to_tty(a->terminal, 1 /* - exit if open fails */); 372 open_stdio_to_tty(a->terminal, 1 /* - exit if open fails */);
354 373
355// NB: do not enable unless you change vfork to fork above
356#ifdef BUT_RUN_ACTIONS_ALREADY_DOES_WAITING
357 /* If the init Action requires us to wait, then force the
358 * supplied terminal to be the controlling tty. */
359 if (a->action_type & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN | RESTART)) {
360 /* Now fork off another process to just hang around */
361 pid = fork();
362 if (pid < 0) {
363 message(L_LOG | L_CONSOLE, "can't fork");
364 _exit(EXIT_FAILURE);
365 }
366
367 if (pid > 0) {
368 /* Parent - wait till the child is done */
369 bb_signals(0
370 + (1 << SIGINT)
371 + (1 << SIGTSTP)
372 + (1 << SIGQUIT)
373 , SIG_IGN);
374 signal(SIGCHLD, SIG_DFL);
375
376 waitfor(pid);
377 /* See if stealing the controlling tty back is necessary */
378 if (tcgetpgrp(0) != getpid())
379 _exit(EXIT_SUCCESS);
380
381 /* Use a temporary process to steal the controlling tty. */
382 pid = fork();
383 if (pid < 0) {
384 message(L_LOG | L_CONSOLE, "can't fork");
385 _exit(EXIT_FAILURE);
386 }
387 if (pid == 0) {
388 setsid();
389 ioctl(0, TIOCSCTTY, 1);
390 _exit(EXIT_SUCCESS);
391 }
392 waitfor(pid);
393 _exit(EXIT_SUCCESS);
394 }
395 /* Child - fall though to actually execute things */
396 }
397#endif
398
399 /* NB: on NOMMU we can't wait for input in child, so 374 /* NB: on NOMMU we can't wait for input in child, so
400 * "askfirst" will work the same as "respawn". */ 375 * "askfirst" will work the same as "respawn". */
401 if (BB_MMU && (a->action_type & ASKFIRST)) { 376 if (BB_MMU && (a->action_type & ASKFIRST)) {
@@ -449,21 +424,32 @@ static pid_t run(const struct init_action *a)
449 424
450static void delete_init_action(struct init_action *action) 425static void delete_init_action(struct init_action *action)
451{ 426{
452 struct init_action *a, *b = NULL; 427 struct init_action *a, **nextp;
453 428
454 for (a = init_action_list; a; b = a, a = a->next) { 429 nextp = &init_action_list;
430 while ((a = *nextp) != NULL) {
455 if (a == action) { 431 if (a == action) {
456 if (b == NULL) { 432 *nextp = a->next;
457 init_action_list = a->next;
458 } else {
459 b->next = a->next;
460 }
461 free(a); 433 free(a);
462 break; 434 break;
463 } 435 }
436 nextp = &a->next;
464 } 437 }
465} 438}
466 439
440static struct init_action *mark_terminated(int pid)
441{
442 struct init_action *a;
443
444 for (a = init_action_list; a; a = a->next) {
445 if (a->pid == pid) {
446 a->pid = 0;
447 return a;
448 }
449 }
450 return NULL;
451}
452
467static void waitfor(pid_t pid) 453static void waitfor(pid_t pid)
468{ 454{
469 /* waitfor(run(x)): protect against failed fork inside run() */ 455 /* waitfor(run(x)): protect against failed fork inside run() */
@@ -472,176 +458,71 @@ static void waitfor(pid_t pid)
472 458
473 /* Wait for any child (prevent zombies from exiting orphaned processes) 459 /* Wait for any child (prevent zombies from exiting orphaned processes)
474 * but exit the loop only when specified one has exited. */ 460 * but exit the loop only when specified one has exited. */
475 while (wait(NULL) != pid) 461 while (1) {
476 continue; 462 pid_t wpid = wait(NULL);
463 mark_terminated(wpid);
464 /* Unsafe. SIGTSTP handler might have wait'ed it already */
465 /*if (wpid == pid) break;*/
466 /* More reliable */
467 if (kill(pid, 0))
468 break;
469 }
477} 470}
478 471
479/* Run all commands of a particular type */ 472/* Run all commands of a particular type */
480static void run_actions(int action_type) 473static void run_actions(int action_type)
481{ 474{
482 struct init_action *a, *tmp;
483
484 for (a = init_action_list; a; a = tmp) {
485 tmp = a->next;
486 if (a->action_type & action_type) {
487 // Pointless: run() will error out if open of device fails.
488 ///* a->terminal of "" means "init's console" */
489 //if (a->terminal[0] && access(a->terminal, R_OK | W_OK)) {
490 // //message(L_LOG | L_CONSOLE, "Device %s cannot be opened in RW mode", a->terminal /*, strerror(errno)*/);
491 // delete_init_action(a);
492 //} else
493 if (a->action_type & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN | RESTART)) {
494 waitfor(run(a));
495 delete_init_action(a);
496 } else if (a->action_type & ONCE) {
497 run(a);
498 delete_init_action(a);
499 } else if (a->action_type & (RESPAWN | ASKFIRST)) {
500 /* Only run stuff with pid==0. If they have
501 * a pid, that means it is still running */
502 if (a->pid == 0) {
503 a->pid = run(a);
504 }
505 }
506 }
507 }
508}
509
510static void low_level_reboot(unsigned long magic)
511{
512 pid_t pid;
513 /* We have to fork here, since the kernel calls do_exit(EXIT_SUCCESS) in
514 * linux/kernel/sys.c, which can cause the machine to panic when
515 * the init process is killed.... */
516 pid = vfork();
517 if (pid == 0) { /* child */
518 reboot(magic);
519 _exit(EXIT_SUCCESS);
520 }
521 waitfor(pid);
522}
523
524static void kill_all_processes(void)
525{
526 /* run everything to be run at "shutdown". This is done _prior_
527 * to killing everything, in case people wish to use scripts to
528 * shut things down gracefully... */
529 run_actions(SHUTDOWN);
530
531 /* first disable all our signals */
532 sigprocmask_allsigs(SIG_BLOCK);
533
534 message(L_CONSOLE | L_LOG, "The system is going down NOW!");
535
536 /* Allow Ctrl-Alt-Del to reboot system. */
537 low_level_reboot(RB_ENABLE_CAD);
538
539 /* Send signals to every process _except_ pid 1 */
540 message(L_CONSOLE | L_LOG, "Sending SIG%s to all processes", "TERM");
541 kill(-1, SIGTERM);
542 sync();
543 sleep(1);
544
545 message(L_CONSOLE | L_LOG, "Sending SIG%s to all processes", "KILL");
546 kill(-1, SIGKILL);
547 sync();
548 sleep(1);
549}
550
551static void halt_reboot_pwoff(int sig)
552{
553 const char *m = "halt";
554 int rb;
555
556 kill_all_processes();
557
558 rb = RB_HALT_SYSTEM;
559 if (sig == SIGTERM) {
560 m = "reboot";
561 rb = RB_AUTOBOOT;
562 } else if (sig == SIGUSR2) {
563 m = "poweroff";
564 rb = RB_POWER_OFF;
565 }
566 message(L_CONSOLE | L_LOG, "Requesting system %s", m);
567 /* allow time for last message to reach serial console */
568 sleep(2);
569 low_level_reboot(rb);
570 loop_forever();
571}
572
573/* Handler for QUIT - exec "restart" action,
574 * else (no such action defined) do nothing */
575static void restart_handler(int sig UNUSED_PARAM)
576{
577 struct init_action *a; 475 struct init_action *a;
578 476
579 for (a = init_action_list; a; a = a->next) { 477 for (a = init_action_list; a; a = a->next) {
580 if (a->action_type & RESTART) { 478 if (!(a->action_type & action_type))
581 kill_all_processes(); 479 continue;
582
583 /* unblock all signals (blocked in kill_all_processes()) */
584 sigprocmask_allsigs(SIG_UNBLOCK);
585
586 /* Open the new terminal device */
587 open_stdio_to_tty(a->terminal, 0 /* - halt if open fails */);
588 480
589 messageD(L_CONSOLE | L_LOG, "Trying to re-exec %s", a->command); 481 if (a->action_type & (SYSINIT | WAIT | ONCE | CTRLALTDEL | SHUTDOWN)) {
590 init_exec(a->command); 482 pid_t pid = run(a);
591 sleep(2); 483 if (a->action_type & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN))
592 low_level_reboot(RB_HALT_SYSTEM); 484 waitfor(pid);
593 loop_forever(); 485 }
486 if (a->action_type & (RESPAWN | ASKFIRST)) {
487 /* Only run stuff with pid == 0. If pid != 0,
488 * it is already running
489 */
490 if (a->pid == 0)
491 a->pid = run(a);
594 } 492 }
595 } 493 }
596} 494}
597 495
598static void ctrlaltdel_signal(int sig UNUSED_PARAM)
599{
600 run_actions(CTRLALTDEL);
601}
602
603/* The SIGCONT handler is set to record_signo().
604 * It just sets bb_got_signal = SIGCONT. */
605
606/* The SIGSTOP & SIGTSTP handler */
607static void stop_handler(int sig UNUSED_PARAM)
608{
609 int saved_errno = errno;
610
611 bb_got_signal = 0;
612 while (bb_got_signal == 0)
613 pause();
614
615 errno = saved_errno;
616}
617
618static void new_init_action(uint8_t action_type, const char *command, const char *cons) 496static void new_init_action(uint8_t action_type, const char *command, const char *cons)
619{ 497{
620 struct init_action *a, *last; 498 struct init_action *a, **nextp;
621 499
622// Why? 500//BUG
623// if (strcmp(cons, bb_dev_null) == 0 && (action & ASKFIRST)) 501//old:
624// return; 502//::shutdown:umount -a -r
625 503//::shutdown:swapoff -a
626 /* Append to the end of the list */ 504//new: swapped:
627 for (a = last = init_action_list; a; a = a->next) { 505//::shutdown:swapoff -a
628 /* don't enter action if it's already in the list, 506//::shutdown:umount -a -r
629 * but do overwrite existing actions */ 507//on SIGHUP, new one will be loaded, but order will be wrong.
508 nextp = &init_action_list;
509 while ((a = *nextp) != NULL) {
510 /* Don't enter action if it's already in the list,
511 * just overwrite existing one's type.
512 * This prevents losing running RESPAWNs.
513 */
630 if ((strcmp(a->command, command) == 0) 514 if ((strcmp(a->command, command) == 0)
631 && (strcmp(a->terminal, cons) == 0) 515 && (strcmp(a->terminal, cons) == 0)
632 ) { 516 ) {
633 a->action_type = action_type; 517 a->action_type = action_type;
634 return; 518 return;
635 } 519 }
636 last = a; 520 nextp = &a->next;
637 } 521 }
638 522
523 /* Append to the end of the list */
639 a = xzalloc(sizeof(*a)); 524 a = xzalloc(sizeof(*a));
640 if (last) { 525 *nextp = a;
641 last->next = a;
642 } else {
643 init_action_list = a;
644 }
645 a->action_type = action_type; 526 a->action_type = action_type;
646 safe_strncpy(a->command, command, sizeof(a->command)); 527 safe_strncpy(a->command, command, sizeof(a->command));
647 safe_strncpy(a->terminal, cons, sizeof(a->terminal)); 528 safe_strncpy(a->terminal, cons, sizeof(a->terminal));
@@ -665,7 +546,7 @@ static void parse_inittab(void)
665 if (parser == NULL) 546 if (parser == NULL)
666#endif 547#endif
667 { 548 {
668 /* No inittab file -- set up some default behavior */ 549 /* No inittab file - set up some default behavior */
669 /* Reboot on Ctrl-Alt-Del */ 550 /* Reboot on Ctrl-Alt-Del */
670 new_init_action(CTRLALTDEL, "reboot", ""); 551 new_init_action(CTRLALTDEL, "reboot", "");
671 /* Umount all filesystems on halt/reboot */ 552 /* Umount all filesystems on halt/reboot */
@@ -694,7 +575,7 @@ static void parse_inittab(void)
694 PARSE_NORMAL & ~(PARSE_TRIM | PARSE_COLLAPSE))) { 575 PARSE_NORMAL & ~(PARSE_TRIM | PARSE_COLLAPSE))) {
695 /* order must correspond to SYSINIT..RESTART constants */ 576 /* order must correspond to SYSINIT..RESTART constants */
696 static const char actions[] ALIGN1 = 577 static const char actions[] ALIGN1 =
697 "sysinit\0""respawn\0""askfirst\0""wait\0""once\0" 578 "sysinit\0""wait\0""once\0""respawn\0""askfirst\0"
698 "ctrlaltdel\0""shutdown\0""restart\0"; 579 "ctrlaltdel\0""shutdown\0""restart\0";
699 int action; 580 int action;
700 char *tty = token[0]; 581 char *tty = token[0];
@@ -722,14 +603,172 @@ static void parse_inittab(void)
722#endif 603#endif
723} 604}
724 605
606static void low_level_reboot(unsigned magic) NORETURN;
607static void low_level_reboot(unsigned magic)
608{
609 pid_t pid;
610
611 /* Allow time for last message to reach serial console, etc */
612 sleep(1);
613
614 /* We have to fork here, since the kernel calls do_exit(EXIT_SUCCESS)
615 * in linux/kernel/sys.c, which can cause the machine to panic when
616 * the init process exits... */
617 pid = vfork();
618 if (pid == 0) { /* child */
619 reboot(magic);
620 _exit(EXIT_SUCCESS);
621 }
622 waitfor(pid);
623 while (1)
624 sleep(1);
625}
626
627static void kill_all_processes(void)
628{
629 /* Run everything to be run at "shutdown". This is done _prior_
630 * to killing everything, in case people wish to use scripts to
631 * shut things down gracefully... */
632 run_actions(SHUTDOWN);
633
634 message(L_CONSOLE | L_LOG, "The system is going down NOW!");
635
636 /* Allow Ctrl-Alt-Del to reboot system. */
637 reboot(RB_ENABLE_CAD); /* misnomer */
638
639 /* Send signals to every process _except_ pid 1 */
640 message(L_CONSOLE | L_LOG, "Sending SIG%s to all processes", "TERM");
641 kill(-1, SIGTERM);
642 sync();
643 sleep(1);
644
645 message(L_CONSOLE, "Sending SIG%s to all processes", "KILL");
646 kill(-1, SIGKILL);
647 sync();
648 sleep(1);
649}
650
651/* Signal handling by init:
652 *
653 * For process with PID==1, on entry kernel sets all signals to SIG_DFL
654 * and unmasks all signals. However, for process with PID==1,
655 * default action (SIG_DFL) on any signal is to ignore it,
656 * even for special signals SIGKILL and SIGCONT.
657 * (SIGSTOP is still handled specially, at least in 2.6.20)
658 * Also, any signal can be caught or blocked.
659 *
660 * We install two kinds of handlers, "immediate" and "delayed".
661 *
662 * Immediate handlers execute at any time, even while, say, sysinit
663 * is running.
664 *
665 * Delayed handlers just set a flag variable. The variable is checked
666 * in the main loop and acted upon.
667 *
668 * halt/poweroff/reboot and restart have immediate handlers.
669 * They only traverse linked list of struct action's, never modify it,
670 * this should be safe to do even in signal handler. Also they
671 * never return.
672 *
673 * SIGSTOP and SIGTSTP have immediate handlers. They just wait
674 * for SIGCONT to happen.
675 *
676 * SIGHUP has a delayed handler, because modifying linked list
677 * of struct action's from a signal handler while it is manipulated
678 * by the program may be disastrous.
679 *
680 * Ctrl-Alt-Del has a delayed handler. Not a must, but allowing
681 * it to happen even somewhere inside "sysinit" would be a bit awkward.
682 *
683 * There is a tiny probability that SIGHUP and Ctrl-Alt-Del will collide
684 * and only one will be remebered and acted upon.
685 */
686
687static void halt_reboot_pwoff(int sig)
688{
689 const char *m;
690 unsigned rb;
691
692 kill_all_processes();
693
694 m = "halt";
695 rb = RB_HALT_SYSTEM;
696 if (sig == SIGTERM) {
697 m = "reboot";
698 rb = RB_AUTOBOOT;
699 } else if (sig == SIGUSR2) {
700 m = "poweroff";
701 rb = RB_POWER_OFF;
702 }
703 message(L_CONSOLE, "Requesting system %s", m);
704 low_level_reboot(rb);
705 /* not reached */
706}
707
708/* The SIGSTOP/SIGTSTP handler
709 * NB: inside it, all signals except SIGCONT are masked
710 * via appropriate setup in sigaction().
711 */
712static void stop_handler(int sig UNUSED_PARAM)
713{
714 int saved_errno;
715 smallint saved_bb_got_signal;
716
717 saved_errno = errno;
718 saved_bb_got_signal = bb_got_signal;
719 signal(SIGCONT, record_signo);
720
721 while (1) {
722 pid_t wpid;
723
724 if (bb_got_signal == SIGCONT)
725 break;
726 /* NB: this can accidentally wait() for a process
727 * which we waitfor() elsewhere! waitfor() must have
728 * code which is resilient against this.
729 */
730 wpid = wait_any_nohang(NULL);
731 if (wpid > 0)
732 mark_terminated(wpid);
733 sleep(1);
734 }
735
736 signal(SIGCONT, SIG_DFL);
737 bb_got_signal = saved_bb_got_signal;
738 errno = saved_errno;
739}
740
741/* Handler for QUIT - exec "restart" action,
742 * else (no such action defined) do nothing */
743static void restart_handler(int sig UNUSED_PARAM)
744{
745 struct init_action *a;
746
747 for (a = init_action_list; a; a = a->next) {
748 if (!(a->action_type & RESTART))
749 continue;
750
751 /* Starting from here, we won't return.
752 * Thus don't need to worry about preserving errno
753 * and such.
754 */
755 kill_all_processes();
756 open_stdio_to_tty(a->terminal, 0 /* - halt if open fails */);
757 messageD(L_CONSOLE, "Trying to re-exec %s", a->command);
758 init_exec(a->command);
759 low_level_reboot(RB_HALT_SYSTEM);
760 /* not reached */
761 }
762}
763
725#if ENABLE_FEATURE_USE_INITTAB 764#if ENABLE_FEATURE_USE_INITTAB
726static void reload_inittab(int sig UNUSED_PARAM) 765static void reload_inittab(void)
727{ 766{
728 struct init_action *a, *tmp; 767 struct init_action *a, *tmp;
729 768
730 message(L_LOG, "reloading /etc/inittab"); 769 message(L_LOG, "reloading /etc/inittab");
731 770
732 /* disable old entrys */ 771 /* Disable old entries */
733 for (a = init_action_list; a; a = a->next) { 772 for (a = init_action_list; a; a = a->next) {
734 a->action_type = ONCE; 773 a->action_type = ONCE;
735 } 774 }
@@ -738,47 +777,57 @@ static void reload_inittab(int sig UNUSED_PARAM)
738 777
739 if (ENABLE_FEATURE_KILL_REMOVED) { 778 if (ENABLE_FEATURE_KILL_REMOVED) {
740 /* Be nice and send SIGTERM first */ 779 /* Be nice and send SIGTERM first */
741 for (a = init_action_list; a; a = a->next) { 780 for (a = init_action_list; a; a = a->next)
742 pid_t pid = a->pid; 781 if (a->pid != 0)
743 if ((a->action_type & ONCE) && pid != 0) { 782 kill(a->pid, SIGTERM);
744 kill(pid, SIGTERM);
745 }
746 }
747#if CONFIG_FEATURE_KILL_DELAY 783#if CONFIG_FEATURE_KILL_DELAY
748 /* NB: parent will wait in NOMMU case */ 784 /* NB: parent will wait in NOMMU case */
749 if ((BB_MMU ? fork() : vfork()) == 0) { /* child */ 785 if ((BB_MMU ? fork() : vfork()) == 0) { /* child */
750 sleep(CONFIG_FEATURE_KILL_DELAY); 786 sleep(CONFIG_FEATURE_KILL_DELAY);
751 for (a = init_action_list; a; a = a->next) { 787 for (a = init_action_list; a; a = a->next)
752 pid_t pid = a->pid; 788 if (a->pid != 0)
753 if ((a->action_type & ONCE) && pid != 0) { 789 kill(a->pid, SIGKILL);
754 kill(pid, SIGKILL);
755 }
756 }
757 _exit(EXIT_SUCCESS); 790 _exit(EXIT_SUCCESS);
758 } 791 }
759#endif 792#endif
760 } 793 }
761 794
762 /* remove unused entrys */ 795 /* Remove old and unused entries */
763 for (a = init_action_list; a; a = tmp) { 796 for (a = init_action_list; a; a = tmp) {
764 tmp = a->next; 797 tmp = a->next;
765 if ((a->action_type & (ONCE | SYSINIT | WAIT)) && a->pid == 0) { 798 if (a->action_type & (ONCE | SYSINIT | WAIT))
766 delete_init_action(a); 799 delete_init_action(a);
767 }
768 } 800 }
769 run_actions(RESPAWN | ASKFIRST); 801 /* Not needed: */
802 /* run_actions(RESPAWN | ASKFIRST); */
803 /* - we return to main loop, which does this automagically */
770} 804}
771#else
772void reload_inittab(int sig);
773#endif 805#endif
774 806
807static int check_delayed_sigs(void)
808{
809 int sigs_seen = 0;
810
811 while (1) {
812 smallint sig = bb_got_signal;
813
814 if (!sig)
815 return sigs_seen;
816 bb_got_signal = 0;
817 sigs_seen = 1;
818#if ENABLE_FEATURE_USE_INITTAB
819 if (sig == SIGHUP)
820 reload_inittab();
821#endif
822 if (sig == SIGINT)
823 run_actions(CTRLALTDEL);
824 }
825}
826
775int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 827int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
776int init_main(int argc UNUSED_PARAM, char **argv) 828int init_main(int argc UNUSED_PARAM, char **argv)
777{ 829{
778 struct init_action *a; 830 die_sleep = 30 * 24*60*60; /* if xmalloc would ever die... */
779 pid_t wpid;
780
781 die_sleep = 30 * 24*60*60; /* if xmalloc will ever die... */
782 831
783 if (argv[1] && !strcmp(argv[1], "-q")) { 832 if (argv[1] && !strcmp(argv[1], "-q")) {
784 return kill(1, SIGHUP); 833 return kill(1, SIGHUP);
@@ -791,28 +840,9 @@ int init_main(int argc UNUSED_PARAM, char **argv)
791 ) { 840 ) {
792 bb_show_usage(); 841 bb_show_usage();
793 } 842 }
794 /* Set up sig handlers -- be sure to 843 /* Turn off rebooting via CTL-ALT-DEL - we get a
795 * clear all of these in run() */
796// TODO: handlers should just set a flag variable.
797// Move signal handling from handlers to main loop -
798// we have bad races otherwise.
799// E.g. parse_inittab() vs. delete_init_action()...
800 signal(SIGQUIT, restart_handler);
801 bb_signals(0
802 + (1 << SIGUSR1) /* halt */
803 + (1 << SIGUSR2) /* poweroff */
804 + (1 << SIGTERM) /* reboot */
805 , halt_reboot_pwoff);
806 signal(SIGINT, ctrlaltdel_signal);
807 signal(SIGCONT, record_signo);
808 bb_signals(0
809 + (1 << SIGSTOP)
810 + (1 << SIGTSTP)
811 , stop_handler);
812
813 /* Turn off rebooting via CTL-ALT-DEL -- we get a
814 * SIGINT on CAD so we can shut things down gracefully... */ 844 * SIGINT on CAD so we can shut things down gracefully... */
815 low_level_reboot(RB_DISABLE_CAD); 845 reboot(RB_DISABLE_CAD); /* misnomer */
816 } 846 }
817 847
818 /* Figure out where the default console should be */ 848 /* Figure out where the default console should be */
@@ -857,11 +887,11 @@ int init_main(int argc UNUSED_PARAM, char **argv)
857 /* Start a shell on console */ 887 /* Start a shell on console */
858 new_init_action(RESPAWN, bb_default_login_shell, ""); 888 new_init_action(RESPAWN, bb_default_login_shell, "");
859 } else { 889 } else {
860 /* Not in single user mode -- see what inittab says */ 890 /* Not in single user mode - see what inittab says */
861 891
862 /* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined, 892 /* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined,
863 * then parse_inittab() simply adds in some default 893 * then parse_inittab() simply adds in some default
864 * actions(i.e., runs INIT_SCRIPT and then starts a pair 894 * actions(i.e., INIT_SCRIPT and a pair
865 * of "askfirst" shells */ 895 * of "askfirst" shells */
866 parse_inittab(); 896 parse_inittab();
867 } 897 }
@@ -888,44 +918,91 @@ int init_main(int argc UNUSED_PARAM, char **argv)
888 while (*++argv) 918 while (*++argv)
889 memset(*argv, 0, strlen(*argv)); 919 memset(*argv, 0, strlen(*argv));
890 920
891 /* Now run everything that needs to be run */ 921 /* Set up signal handlers */
922 if (!DEBUG_INIT) {
923 struct sigaction sa;
892 924
925 bb_signals(0
926 + (1 << SIGUSR1) /* halt */
927 + (1 << SIGTERM) /* reboot */
928 + (1 << SIGUSR2) /* poweroff */
929 , halt_reboot_pwoff);
930 signal(SIGQUIT, restart_handler); /* re-exec another init */
931
932 /* Stop handler must allow only SIGCONT inside itself */
933 memset(&sa, 0, sizeof(sa));
934 sigfillset(&sa.sa_mask);
935 sigdelset(&sa.sa_mask, SIGCONT);
936 sa.sa_handler = stop_handler;
937 /* NB: sa_flags doesn't have SA_RESTART.
938 * It must be able to interrupt wait().
939 */
940 sigaction_set(SIGTSTP, &sa); /* pause */
941 /* Does not work as intended, at least in 2.6.20.
942 * SIGSTOP is simply ignored by init:
943 */
944 sigaction_set(SIGSTOP, &sa); /* pause */
945
946 /* SIGINT (Ctrl-Alt-Del) must interrupt wait(),
947 * setting handler without SA_RESTART flag.
948 */
949 bb_signals_recursive_norestart((1 << SIGINT), record_signo);
950 }
951
952 /* Now run everything that needs to be run */
893 /* First run the sysinit command */ 953 /* First run the sysinit command */
894 run_actions(SYSINIT); 954 run_actions(SYSINIT);
895 955 check_delayed_sigs();
896 /* Next run anything that wants to block */ 956 /* Next run anything that wants to block */
897 run_actions(WAIT); 957 run_actions(WAIT);
898 958 check_delayed_sigs();
899 /* Next run anything to be run only once */ 959 /* Next run anything to be run only once */
900 run_actions(ONCE); 960 run_actions(ONCE);
901 961
902 /* Redefine SIGHUP to reread /etc/inittab */ 962 /* Set up "reread /etc/inittab" handler.
903 signal(SIGHUP, ENABLE_FEATURE_USE_INITTAB ? reload_inittab : SIG_IGN); 963 * Handler is set up without SA_RESTART, it will interrupt syscalls.
964 */
965 if (!DEBUG_INIT && ENABLE_FEATURE_USE_INITTAB)
966 bb_signals_recursive_norestart((1 << SIGHUP), record_signo);
904 967
905 /* Now run the looping stuff for the rest of forever */ 968 /* Now run the looping stuff for the rest of forever.
969 * NB: if delayed signal happened, avoid blocking in wait().
970 */
906 while (1) { 971 while (1) {
907 /* run the respawn/askfirst stuff */ 972 pid_t wpid;
973 int got_sigs;
974
975 got_sigs = check_delayed_sigs();
976
977 /* (Re)run the respawn/askfirst stuff */
908 run_actions(RESPAWN | ASKFIRST); 978 run_actions(RESPAWN | ASKFIRST);
909 979
910 /* Don't consume all CPU time -- sleep a bit */ 980 got_sigs |= check_delayed_sigs();
981
982 /* Don't consume all CPU time - sleep a bit */
911 sleep(1); 983 sleep(1);
912 984
913 /* Wait for any child process to exit */ 985 got_sigs |= check_delayed_sigs();
986
987 /* Wait for any child process to exit.
988 * NB: "delayed" signals will also interrupt this wait(),
989 * bb_signals_recursive_norestart() set them up for that.
990 * This guarantees we won't be stuck here
991 * till next orphan dies.
992 */
993 if (got_sigs)
994 goto dont_block;
914 wpid = wait(NULL); 995 wpid = wait(NULL);
915 while (wpid > 0) { 996 while (wpid > 0) {
916 /* Find out who died and clean up their corpse */ 997 struct init_action *a = mark_terminated(wpid);
917 for (a = init_action_list; a; a = a->next) { 998 if (a) {
918 if (a->pid == wpid) { 999 message(L_LOG, "process '%s' (pid %d) exited. "
919 /* Set the pid to 0 so that the process gets 1000 "Scheduling for restart.",
920 * restarted by run_actions() */ 1001 a->command, wpid);
921 a->pid = 0;
922 message(L_LOG, "process '%s' (pid %d) exited. "
923 "Scheduling for restart.",
924 a->command, wpid);
925 }
926 } 1002 }
927 /* see if anyone else is waiting to be reaped */ 1003 /* See if anyone else is waiting to be reaped */
1004 dont_block:
928 wpid = wait_any_nohang(NULL); 1005 wpid = wait_any_nohang(NULL);
929 } 1006 }
930 } 1007 } /* while (1) */
931} 1008}