1/* vi: set sw=4 ts=4: */ 2/* 3 * Mini init implementation for busybox 4 * 5 * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>. 6 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 7 * Adjusted by so many folks, it's impossible to keep track. 8 * 9 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 10 */ 11 12#include "libbb.h" 13#include <syslog.h> 14#include <paths.h> 15#include <sys/reboot.h> 16#include <sys/resource.h> 17#include <linux/vt.h> 18#if ENABLE_FEATURE_UTMP 19# include <utmp.h> /* DEAD_PROCESS */ 20#endif 21 22 23/* Was a CONFIG_xxx option. A lot of people were building 24 * not fully functional init by switching it on! */ 25#define DEBUG_INIT 0 26 27#define COMMAND_SIZE 256 28#define CONSOLE_NAME_SIZE 32 29 30/* Default sysinit script. */ 31#ifndef INIT_SCRIPT 32#define INIT_SCRIPT "/etc/init.d/rcS" 33#endif 34 35/* Each type of actions can appear many times. They will be 36 * handled in order. RESTART is an exception, only 1st is used. 37 */ 38/* Start these actions first and wait for completion */ 39#define SYSINIT 0x01 40/* Start these after SYSINIT and wait for completion */ 41#define WAIT 0x02 42/* Start these after WAIT and *dont* wait for completion */ 43#define ONCE 0x04 44/* 45 * NB: while SYSINIT/WAIT/ONCE are being processed, 46 * SIGHUP ("reread /etc/inittab") will be processed only after 47 * each group of actions. If new inittab adds, say, a SYSINIT action, 48 * it will not be run, since init is already "past SYSINIT stage". 49 */ 50/* Start these after ONCE are started, restart on exit */ 51#define RESPAWN 0x08 52/* Like RESPAWN, but wait for <Enter> to be pressed on tty */ 53#define ASKFIRST 0x10 54/* 55 * Start these on SIGINT, and wait for completion. 56 * Then go back to respawning RESPAWN and ASKFIRST actions. 57 * NB: kernel sends SIGINT to us if Ctrl-Alt-Del was pressed. 58 */ 59#define CTRLALTDEL 0x20 60/* 61 * Start these before killing all processes in preparation for 62 * running RESTART actions or doing low-level halt/reboot/poweroff 63 * (initiated by SIGUSR1/SIGTERM/SIGUSR2). 64 * Wait for completion before proceeding. 65 */ 66#define SHUTDOWN 0x40 67/* 68 * exec() on SIGQUIT. SHUTDOWN actions are started and waited for, 69 * then all processes are killed, then init exec's 1st RESTART action, 70 * replacing itself by it. If no RESTART action specified, 71 * SIGQUIT has no effect. 72 */ 73#define RESTART 0x80 74 75 76/* A linked list of init_actions, to be read from inittab */ 77struct init_action { 78 struct init_action *next; 79 pid_t pid; 80 uint8_t action_type; 81 char terminal[CONSOLE_NAME_SIZE]; 82 char command[COMMAND_SIZE]; 83}; 84 85static struct init_action *init_action_list = NULL; 86 87static const char *log_console = VC_5; 88 89enum { 90 L_LOG = 0x1, 91 L_CONSOLE = 0x2, 92#ifndef RB_HALT_SYSTEM 93 RB_HALT_SYSTEM = 0xcdef0123, /* FIXME: this overflows enum */ 94 RB_ENABLE_CAD = 0x89abcdef, 95 RB_DISABLE_CAD = 0, 96 RB_POWER_OFF = 0x4321fedc, 97 RB_AUTOBOOT = 0x01234567, 98#endif 99}; 100 101/* Print a message to the specified device. 102 * "where" may be bitwise-or'd from L_LOG | L_CONSOLE 103 * NB: careful, we can be called after vfork! 104 */ 105#define dbg_message(...) do { if (DEBUG_INIT) message(__VA_ARGS__); } while (0) 106static void message(int where, const char *fmt, ...) 107 __attribute__ ((format(printf, 2, 3))); 108static void message(int where, const char *fmt, ...) 109{ 110 va_list arguments; 111 unsigned l; 112 char msg[128]; 113 114 msg[0] = '\r'; 115 va_start(arguments, fmt); 116 l = 1 + vsnprintf(msg + 1, sizeof(msg) - 2, fmt, arguments); 117 if (l > sizeof(msg) - 1) 118 l = sizeof(msg) - 1; 119 va_end(arguments); 120 121#if ENABLE_FEATURE_INIT_SYSLOG 122 msg[l] = '\0'; 123 if (where & L_LOG) { 124 /* Log the message to syslogd */ 125 openlog(applet_name, 0, LOG_DAEMON); 126 /* don't print "\r" */ 127 syslog(LOG_INFO, "%s", msg + 1); 128 closelog(); 129 } 130 msg[l++] = '\n'; 131 msg[l] = '\0'; 132#else 133 { 134 static int log_fd = -1; 135 136 msg[l++] = '\n'; 137 msg[l] = '\0'; 138 /* Take full control of the log tty, and never close it. 139 * It's mine, all mine! Muhahahaha! */ 140 if (log_fd < 0) { 141 if (!log_console) { 142 log_fd = STDERR_FILENO; 143 } else { 144 log_fd = device_open(log_console, O_WRONLY | O_NONBLOCK | O_NOCTTY); 145 if (log_fd < 0) { 146 bb_error_msg("can't log to %s", log_console); 147 where = L_CONSOLE; 148 } else { 149 close_on_exec_on(log_fd); 150 } 151 } 152 } 153 if (where & L_LOG) { 154 full_write(log_fd, msg, l); 155 if (log_fd == STDERR_FILENO) 156 return; /* don't print dup messages */ 157 } 158 } 159#endif 160 161 if (where & L_CONSOLE) { 162 /* Send console messages to console so people will see them. */ 163 full_write(STDERR_FILENO, msg, l); 164 } 165} 166 167static void console_init(void) 168{ 169 int vtno; 170 char *s; 171 172 s = getenv("CONSOLE"); 173 if (!s) 174 s = getenv("console"); 175 if (s) { 176 int fd = open(s, O_RDWR | O_NONBLOCK | O_NOCTTY); 177 if (fd >= 0) { 178 dup2(fd, STDIN_FILENO); 179 dup2(fd, STDOUT_FILENO); 180 xmove_fd(fd, STDERR_FILENO); 181 } 182 dbg_message(L_LOG, "console='%s'", s); 183 } else { 184 /* Make sure fd 0,1,2 are not closed 185 * (so that they won't be used by future opens) */ 186 bb_sanitize_stdio(); 187// Users report problems 188// /* Make sure init can't be blocked by writing to stderr */ 189// fcntl(STDERR_FILENO, F_SETFL, fcntl(STDERR_FILENO, F_GETFL) | O_NONBLOCK); 190 } 191 192 s = getenv("TERM"); 193 if (ioctl(STDIN_FILENO, VT_OPENQRY, &vtno) != 0) { 194 /* Not a linux terminal, probably serial console. 195 * Force the TERM setting to vt102 196 * if TERM is set to linux (the default) */ 197 if (!s || strcmp(s, "linux") == 0) 198 putenv((char*)"TERM=vt102"); 199 if (!ENABLE_FEATURE_INIT_SYSLOG) 200 log_console = NULL; 201 } else if (!s) 202 putenv((char*)"TERM=linux"); 203} 204 205/* Set terminal settings to reasonable defaults. 206 * NB: careful, we can be called after vfork! */ 207static void set_sane_term(void) 208{ 209 struct termios tty; 210 211 tcgetattr(STDIN_FILENO, &tty); 212 213 /* set control chars */ 214 tty.c_cc[VINTR] = 3; /* C-c */ 215 tty.c_cc[VQUIT] = 28; /* C-\ */ 216 tty.c_cc[VERASE] = 127; /* C-? */ 217 tty.c_cc[VKILL] = 21; /* C-u */ 218 tty.c_cc[VEOF] = 4; /* C-d */ 219 tty.c_cc[VSTART] = 17; /* C-q */ 220 tty.c_cc[VSTOP] = 19; /* C-s */ 221 tty.c_cc[VSUSP] = 26; /* C-z */ 222 223 /* use line discipline 0 */ 224 tty.c_line = 0; 225 226 /* Make it be sane */ 227 tty.c_cflag &= CBAUD | CBAUDEX | CSIZE | CSTOPB | PARENB | PARODD; 228 tty.c_cflag |= CREAD | HUPCL | CLOCAL; 229 230 /* input modes */ 231 tty.c_iflag = ICRNL | IXON | IXOFF; 232 233 /* output modes */ 234 tty.c_oflag = OPOST | ONLCR; 235 236 /* local modes */ 237 tty.c_lflag = 238 ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN; 239 240 tcsetattr_stdin_TCSANOW(&tty); 241} 242 243/* Open the new terminal device. 244 * NB: careful, we can be called after vfork! */ 245static int open_stdio_to_tty(const char* tty_name) 246{ 247 /* empty tty_name means "use init's tty", else... */ 248 if (tty_name[0]) { 249 int fd; 250 251 close(STDIN_FILENO); 252 /* fd can be only < 0 or 0: */ 253 fd = device_open(tty_name, O_RDWR); 254 if (fd) { 255 message(L_LOG | L_CONSOLE, "can't open %s: %s", 256 tty_name, strerror(errno)); 257 return 0; /* failure */ 258 } 259 dup2(STDIN_FILENO, STDOUT_FILENO); 260 dup2(STDIN_FILENO, STDERR_FILENO); 261 } 262 set_sane_term(); 263 return 1; /* success */ 264} 265 266static void reset_sighandlers_and_unblock_sigs(void) 267{ 268 bb_signals(0 269 + (1 << SIGUSR1) 270 + (1 << SIGUSR2) 271 + (1 << SIGTERM) 272 + (1 << SIGQUIT) 273 + (1 << SIGINT) 274 + (1 << SIGHUP) 275 + (1 << SIGTSTP) 276 + (1 << SIGSTOP) 277 , SIG_DFL); 278 sigprocmask_allsigs(SIG_UNBLOCK); 279} 280 281/* Wrapper around exec: 282 * Takes string (max COMMAND_SIZE chars). 283 * If chars like '>' detected, execs '[-]/bin/sh -c "exec ......."'. 284 * Otherwise splits words on whitespace, deals with leading dash, 285 * and uses plain exec(). 286 * NB: careful, we can be called after vfork! 287 */ 288static void init_exec(const char *command) 289{ 290 char *cmd[COMMAND_SIZE / 2]; 291 char buf[COMMAND_SIZE + 6]; /* COMMAND_SIZE+strlen("exec ")+1 */ 292 int dash = (command[0] == '-' /* maybe? && command[1] == '/' */); 293 294 /* See if any special /bin/sh requiring characters are present */ 295 if (strpbrk(command, "~`!$^&*()=|\\{}[];\"'<>?") != NULL) { 296 strcpy(buf, "exec "); 297 strcpy(buf + 5, command + dash); /* excluding "-" */ 298 /* NB: LIBBB_DEFAULT_LOGIN_SHELL define has leading dash */ 299 cmd[0] = (char*)(LIBBB_DEFAULT_LOGIN_SHELL + !dash); 300 cmd[1] = (char*)"-c"; 301 cmd[2] = buf; 302 cmd[3] = NULL; 303 } else { 304 /* Convert command (char*) into cmd (char**, one word per string) */ 305 char *word, *next; 306 int i = 0; 307 next = strcpy(buf, command); /* including "-" */ 308 while ((word = strsep(&next, " \t")) != NULL) { 309 if (*word != '\0') { /* not two spaces/tabs together? */ 310 cmd[i] = word; 311 i++; 312 } 313 } 314 cmd[i] = NULL; 315 } 316 /* If we saw leading "-", it is interactive shell. 317 * Try harder to give it a controlling tty. 318 * And skip "-" in actual exec call. */ 319 if (dash) { 320 /* _Attempt_ to make stdin a controlling tty. */ 321 if (ENABLE_FEATURE_INIT_SCTTY) 322 ioctl(STDIN_FILENO, TIOCSCTTY, 0 /*only try, don't steal*/); 323 } 324 BB_EXECVP(cmd[0] + dash, cmd); 325 message(L_LOG | L_CONSOLE, "can't run '%s': %s", cmd[0], strerror(errno)); 326 /* returns if execvp fails */ 327} 328 329/* Used only by run_actions */ 330static pid_t run(const struct init_action *a) 331{ 332 pid_t pid; 333 334 /* Careful: don't be affected by a signal in vforked child */ 335 sigprocmask_allsigs(SIG_BLOCK); 336 if (BB_MMU && (a->action_type & ASKFIRST)) 337 pid = fork(); 338 else 339 pid = vfork(); 340 if (pid < 0) 341 message(L_LOG | L_CONSOLE, "can't fork"); 342 if (pid) { 343 sigprocmask_allsigs(SIG_UNBLOCK); 344 return pid; /* Parent or error */ 345 } 346 347 /* Child */ 348 349 /* Reset signal handlers that were set by the parent process */ 350 reset_sighandlers_and_unblock_sigs(); 351 352 /* Create a new session and make ourself the process group leader */ 353 setsid(); 354 355 /* Open the new terminal device */ 356 if (!open_stdio_to_tty(a->terminal)) 357 _exit(EXIT_FAILURE); 358 359 /* NB: on NOMMU we can't wait for input in child, so 360 * "askfirst" will work the same as "respawn". */ 361 if (BB_MMU && (a->action_type & ASKFIRST)) { 362 static const char press_enter[] ALIGN1 = 363#ifdef CUSTOMIZED_BANNER 364#include CUSTOMIZED_BANNER 365#endif 366 "\nPlease press Enter to activate this console. "; 367 char c; 368 /* 369 * Save memory by not exec-ing anything large (like a shell) 370 * before the user wants it. This is critical if swap is not 371 * enabled and the system has low memory. Generally this will 372 * be run on the second virtual console, and the first will 373 * be allowed to start a shell or whatever an init script 374 * specifies. 375 */ 376 dbg_message(L_LOG, "waiting for enter to start '%s'" 377 "(pid %d, tty '%s')\n", 378 a->command, getpid(), a->terminal); 379 full_write(STDOUT_FILENO, press_enter, sizeof(press_enter) - 1); 380 while (safe_read(STDIN_FILENO, &c, 1) == 1 && c != '\n') 381 continue; 382 } 383 384 /* 385 * When a file named /.init_enable_core exists, setrlimit is called 386 * before processes are spawned to set core file size as unlimited. 387 * This is for debugging only. Don't use this is production, unless 388 * you want core dumps lying about.... 389 */ 390 if (ENABLE_FEATURE_INIT_COREDUMPS) { 391 if (access("/.init_enable_core", F_OK) == 0) { 392 struct rlimit limit; 393 limit.rlim_cur = RLIM_INFINITY; 394 limit.rlim_max = RLIM_INFINITY; 395 setrlimit(RLIMIT_CORE, &limit); 396 } 397 } 398 399 /* Log the process name and args */ 400 message(L_LOG, "starting pid %d, tty '%s': '%s'", 401 getpid(), a->terminal, a->command); 402 403 /* Now run it. The new program will take over this PID, 404 * so nothing further in init.c should be run. */ 405 init_exec(a->command); 406 /* We're still here? Some error happened. */ 407 _exit(-1); 408} 409 410static struct init_action *mark_terminated(pid_t pid) 411{ 412 struct init_action *a; 413 414 if (pid > 0) { 415 for (a = init_action_list; a; a = a->next) { 416 if (a->pid == pid) { 417 a->pid = 0; 418 return a; 419 } 420 } 421 update_utmp(pid, DEAD_PROCESS, /*tty_name:*/ NULL, /*username:*/ NULL, /*hostname:*/ NULL); 422 } 423 return NULL; 424} 425 426static void waitfor(pid_t pid) 427{ 428 /* waitfor(run(x)): protect against failed fork inside run() */ 429 if (pid <= 0) 430 return; 431 432 /* Wait for any child (prevent zombies from exiting orphaned processes) 433 * but exit the loop only when specified one has exited. */ 434 while (1) { 435 pid_t wpid = wait(NULL); 436 mark_terminated(wpid); 437 /* Unsafe. SIGTSTP handler might have wait'ed it already */ 438 /*if (wpid == pid) break;*/ 439 /* More reliable: */ 440 if (kill(pid, 0)) 441 break; 442 } 443} 444 445/* Run all commands of a particular type */ 446static void run_actions(int action_type) 447{ 448 struct init_action *a; 449 450 for (a = init_action_list; a; a = a->next) { 451 if (!(a->action_type & action_type)) 452 continue; 453 454 if (a->action_type & (SYSINIT | WAIT | ONCE | CTRLALTDEL | SHUTDOWN)) { 455 pid_t pid = run(a); 456 if (a->action_type & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN)) 457 waitfor(pid); 458 } 459 if (a->action_type & (RESPAWN | ASKFIRST)) { 460 /* Only run stuff with pid == 0. If pid != 0, 461 * it is already running 462 */ 463 if (a->pid == 0) 464 a->pid = run(a); 465 } 466 } 467} 468 469static void new_init_action(uint8_t action_type, const char *command, const char *cons) 470{ 471 struct init_action *a, **nextp; 472 473 /* Scenario: 474 * old inittab: 475 * ::shutdown:umount -a -r 476 * ::shutdown:swapoff -a 477 * new inittab: 478 * ::shutdown:swapoff -a 479 * ::shutdown:umount -a -r 480 * On reload, we must ensure entries end up in correct order. 481 * To achieve that, if we find a matching entry, we move it 482 * to the end. 483 */ 484 nextp = &init_action_list; 485 while ((a = *nextp) != NULL) { 486 /* Don't enter action if it's already in the list, 487 * This prevents losing running RESPAWNs. 488 */ 489 if (strcmp(a->command, command) == 0 490 && strcmp(a->terminal, cons) == 0 491 ) { 492 /* Remove from list */ 493 *nextp = a->next; 494 /* Find the end of the list */ 495 while (*nextp != NULL) 496 nextp = &(*nextp)->next; 497 a->next = NULL; 498 break; 499 } 500 nextp = &a->next; 501 } 502 503 if (!a) 504 a = xzalloc(sizeof(*a)); 505 /* Append to the end of the list */ 506 *nextp = a; 507 a->action_type = action_type; 508 safe_strncpy(a->command, command, sizeof(a->command)); 509 safe_strncpy(a->terminal, cons, sizeof(a->terminal)); 510 dbg_message(L_LOG | L_CONSOLE, "command='%s' action=%d tty='%s'\n", 511 a->command, a->action_type, a->terminal); 512} 513 514/* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined, 515 * then parse_inittab() simply adds in some default 516 * actions(i.e., runs INIT_SCRIPT and then starts a pair 517 * of "askfirst" shells). If CONFIG_FEATURE_USE_INITTAB 518 * _is_ defined, but /etc/inittab is missing, this 519 * results in the same set of default behaviors. 520 */ 521static void parse_inittab(void) 522{ 523#if ENABLE_FEATURE_USE_INITTAB 524 char *token[4]; 525 parser_t *parser = config_open2("/etc/inittab", fopen_for_read); 526 527 if (parser == NULL) 528#endif 529 { 530 /* No inittab file - set up some default behavior */ 531 /* Reboot on Ctrl-Alt-Del */ 532 new_init_action(CTRLALTDEL, "reboot", ""); 533 /* Umount all filesystems on halt/reboot */ 534 new_init_action(SHUTDOWN, "umount -a -r", ""); 535 /* Swapoff on halt/reboot */ 536 if (ENABLE_SWAPONOFF) 537 new_init_action(SHUTDOWN, "swapoff -a", ""); 538 /* Prepare to restart init when a QUIT is received */ 539 new_init_action(RESTART, "init", ""); 540 /* Askfirst shell on tty1-4 */ 541 new_init_action(ASKFIRST, bb_default_login_shell, ""); 542//TODO: VC_1 instead of ""? "" is console -> ctty problems -> angry users 543 new_init_action(ASKFIRST, bb_default_login_shell, VC_2); 544 new_init_action(ASKFIRST, bb_default_login_shell, VC_3); 545 new_init_action(ASKFIRST, bb_default_login_shell, VC_4); 546 /* sysinit */ 547 new_init_action(SYSINIT, INIT_SCRIPT, ""); 548 return; 549 } 550 551#if ENABLE_FEATURE_USE_INITTAB 552 /* optional_tty:ignored_runlevel:action:command 553 * Delims are not to be collapsed and need exactly 4 tokens 554 */ 555 while (config_read(parser, token, 4, 0, "#:", 556 PARSE_NORMAL & ~(PARSE_TRIM | PARSE_COLLAPSE))) { 557 /* order must correspond to SYSINIT..RESTART constants */ 558 static const char actions[] ALIGN1 = 559 "sysinit\0""wait\0""once\0""respawn\0""askfirst\0" 560 "ctrlaltdel\0""shutdown\0""restart\0"; 561 int action; 562 char *tty = token[0]; 563 564 if (!token[3]) /* less than 4 tokens */ 565 goto bad_entry; 566 action = index_in_strings(actions, token[2]); 567 if (action < 0 || !token[3][0]) /* token[3]: command */ 568 goto bad_entry; 569 /* turn .*TTY -> /dev/TTY */ 570 if (tty[0]) { 571 tty = concat_path_file("/dev/", skip_dev_pfx(tty)); 572 } 573 new_init_action(1 << action, token[3], tty); 574 if (tty[0]) 575 free(tty); 576 continue; 577 bad_entry: 578 message(L_LOG | L_CONSOLE, "Bad inittab entry at line %d", 579 parser->lineno); 580 } 581 config_close(parser); 582#endif 583} 584 585static void pause_and_low_level_reboot(unsigned magic) NORETURN; 586static void pause_and_low_level_reboot(unsigned magic) 587{ 588 pid_t pid; 589 590 /* Allow time for last message to reach serial console, etc */ 591 sleep(1); 592 593 /* We have to fork here, since the kernel calls do_exit(EXIT_SUCCESS) 594 * in linux/kernel/sys.c, which can cause the machine to panic when 595 * the init process exits... */ 596 pid = vfork(); 597 if (pid == 0) { /* child */ 598 reboot(magic); 599 _exit(EXIT_SUCCESS); 600 } 601 while (1) 602 sleep(1); 603} 604 605static void run_shutdown_and_kill_processes(void) 606{ 607 /* Run everything to be run at "shutdown". This is done _prior_ 608 * to killing everything, in case people wish to use scripts to 609 * shut things down gracefully... */ 610 run_actions(SHUTDOWN); 611 612 message(L_CONSOLE | L_LOG, "The system is going down NOW!"); 613 614 /* Send signals to every process _except_ pid 1 */ 615 kill(-1, SIGTERM); 616 message(L_CONSOLE | L_LOG, "Sent SIG%s to all processes", "TERM"); 617 sync(); 618 sleep(1); 619 620 kill(-1, SIGKILL); 621 message(L_CONSOLE, "Sent SIG%s to all processes", "KILL"); 622 sync(); 623 /*sleep(1); - callers take care about making a pause */ 624} 625 626/* Signal handling by init: 627 * 628 * For process with PID==1, on entry kernel sets all signals to SIG_DFL 629 * and unmasks all signals. However, for process with PID==1, 630 * default action (SIG_DFL) on any signal is to ignore it, 631 * even for special signals SIGKILL and SIGCONT. 632 * Also, any signal can be caught or blocked. 633 * (but SIGSTOP is still handled specially, at least in 2.6.20) 634 * 635 * We install two kinds of handlers, "immediate" and "delayed". 636 * 637 * Immediate handlers execute at any time, even while, say, sysinit 638 * is running. 639 * 640 * Delayed handlers just set a flag variable. The variable is checked 641 * in the main loop and acted upon. 642 * 643 * halt/poweroff/reboot and restart have immediate handlers. 644 * They only traverse linked list of struct action's, never modify it, 645 * this should be safe to do even in signal handler. Also they 646 * never return. 647 * 648 * SIGSTOP and SIGTSTP have immediate handlers. They just wait 649 * for SIGCONT to happen. 650 * 651 * SIGHUP has a delayed handler, because modifying linked list 652 * of struct action's from a signal handler while it is manipulated 653 * by the program may be disastrous. 654 * 655 * Ctrl-Alt-Del has a delayed handler. Not a must, but allowing 656 * it to happen even somewhere inside "sysinit" would be a bit awkward. 657 * 658 * There is a tiny probability that SIGHUP and Ctrl-Alt-Del will collide 659 * and only one will be remembered and acted upon. 660 */ 661 662/* The SIGUSR[12]/SIGTERM handler */ 663static void halt_reboot_pwoff(int sig) NORETURN; 664static void halt_reboot_pwoff(int sig) 665{ 666 const char *m; 667 unsigned rb; 668 669 /* We may call run() and it unmasks signals, 670 * including the one masked inside this signal handler. 671 * Testcase which would start multiple reboot scripts: 672 * while true; do reboot; done 673 * Preventing it: 674 */ 675 reset_sighandlers_and_unblock_sigs(); 676 677 run_shutdown_and_kill_processes(); 678 679 m = "halt"; 680 rb = RB_HALT_SYSTEM; 681 if (sig == SIGTERM) { 682 m = "reboot"; 683 rb = RB_AUTOBOOT; 684 } else if (sig == SIGUSR2) { 685 m = "poweroff"; 686 rb = RB_POWER_OFF; 687 } 688 message(L_CONSOLE, "Requesting system %s", m); 689 pause_and_low_level_reboot(rb); 690 /* not reached */ 691} 692 693/* Handler for QUIT - exec "restart" action, 694 * else (no such action defined) do nothing */ 695static void restart_handler(int sig UNUSED_PARAM) 696{ 697 struct init_action *a; 698 699 for (a = init_action_list; a; a = a->next) { 700 if (!(a->action_type & RESTART)) 701 continue; 702 703 /* Starting from here, we won't return. 704 * Thus don't need to worry about preserving errno 705 * and such. 706 */ 707 708 reset_sighandlers_and_unblock_sigs(); 709 710 run_shutdown_and_kill_processes(); 711 712 /* Allow Ctrl-Alt-Del to reboot the system. 713 * This is how kernel sets it up for init, we follow suit. 714 */ 715 reboot(RB_ENABLE_CAD); /* misnomer */ 716 717 if (open_stdio_to_tty(a->terminal)) { 718 dbg_message(L_CONSOLE, "Trying to re-exec %s", a->command); 719 /* Theoretically should be safe. 720 * But in practice, kernel bugs may leave 721 * unkillable processes, and wait() may block forever. 722 * Oh well. Hoping "new" init won't be too surprised 723 * by having children it didn't create. 724 */ 725 //while (wait(NULL) > 0) 726 // continue; 727 init_exec(a->command); 728 } 729 /* Open or exec failed */ 730 pause_and_low_level_reboot(RB_HALT_SYSTEM); 731 /* not reached */ 732 } 733} 734 735/* The SIGSTOP/SIGTSTP handler 736 * NB: inside it, all signals except SIGCONT are masked 737 * via appropriate setup in sigaction(). 738 */ 739static void stop_handler(int sig UNUSED_PARAM) 740{ 741 smallint saved_bb_got_signal; 742 int saved_errno; 743 744 saved_bb_got_signal = bb_got_signal; 745 saved_errno = errno; 746 signal(SIGCONT, record_signo); 747 748 while (1) { 749 pid_t wpid; 750 751 if (bb_got_signal == SIGCONT) 752 break; 753 /* NB: this can accidentally wait() for a process 754 * which we waitfor() elsewhere! waitfor() must have 755 * code which is resilient against this. 756 */ 757 wpid = wait_any_nohang(NULL); 758 mark_terminated(wpid); 759 sleep(1); 760 } 761 762 signal(SIGCONT, SIG_DFL); 763 errno = saved_errno; 764 bb_got_signal = saved_bb_got_signal; 765} 766 767#if ENABLE_FEATURE_USE_INITTAB 768static void reload_inittab(void) 769{ 770 struct init_action *a, **nextp; 771 772 message(L_LOG, "reloading /etc/inittab"); 773 774 /* Disable old entries */ 775 for (a = init_action_list; a; a = a->next) 776 a->action_type = 0; 777 778 /* Append new entries, or modify existing entries 779 * (incl. setting a->action_type) if cmd and device name 780 * match new ones. End result: only entries with 781 * a->action_type == 0 are stale. 782 */ 783 parse_inittab(); 784 785#if ENABLE_FEATURE_KILL_REMOVED 786 /* Kill stale entries */ 787 /* Be nice and send SIGTERM first */ 788 for (a = init_action_list; a; a = a->next) 789 if (a->action_type == 0 && a->pid != 0) 790 kill(a->pid, SIGTERM); 791 if (CONFIG_FEATURE_KILL_DELAY) { 792 /* NB: parent will wait in NOMMU case */ 793 if ((BB_MMU ? fork() : vfork()) == 0) { /* child */ 794 sleep(CONFIG_FEATURE_KILL_DELAY); 795 for (a = init_action_list; a; a = a->next) 796 if (a->action_type == 0 && a->pid != 0) 797 kill(a->pid, SIGKILL); 798 _exit(EXIT_SUCCESS); 799 } 800 } 801#endif 802 803 /* Remove stale entries and SYSINIT entries. 804 * We never rerun SYSINIT entries anyway, 805 * removing them too saves a few bytes */ 806 nextp = &init_action_list; 807 while ((a = *nextp) != NULL) { 808 if ((a->action_type & ~SYSINIT) == 0) { 809 *nextp = a->next; 810 free(a); 811 } else { 812 nextp = &a->next; 813 } 814 } 815 816 /* Not needed: */ 817 /* run_actions(RESPAWN | ASKFIRST); */ 818 /* - we return to main loop, which does this automagically */ 819} 820#endif 821 822static int check_delayed_sigs(void) 823{ 824 int sigs_seen = 0; 825 826 while (1) { 827 smallint sig = bb_got_signal; 828 829 if (!sig) 830 return sigs_seen; 831 bb_got_signal = 0; 832 sigs_seen = 1; 833#if ENABLE_FEATURE_USE_INITTAB 834 if (sig == SIGHUP) 835 reload_inittab(); 836#endif 837 if (sig == SIGINT) 838 run_actions(CTRLALTDEL); 839 } 840} 841 842int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 843int init_main(int argc UNUSED_PARAM, char **argv) 844{ 845 die_sleep = 30 * 24*60*60; /* if xmalloc would ever die... */ 846 847 if (argv[1] && strcmp(argv[1], "-q") == 0) { 848 return kill(1, SIGHUP); 849 } 850 851 if (!DEBUG_INIT) { 852 /* Expect to be invoked as init with PID=1 or be invoked as linuxrc */ 853 if (getpid() != 1 854 && (!ENABLE_FEATURE_INITRD || !strstr(applet_name, "linuxrc")) 855 ) { 856 bb_show_usage(); 857 } 858 /* Turn off rebooting via CTL-ALT-DEL - we get a 859 * SIGINT on CAD so we can shut things down gracefully... */ 860 reboot(RB_DISABLE_CAD); /* misnomer */ 861 } 862 863 /* Figure out where the default console should be */ 864 console_init(); 865 set_sane_term(); 866 xchdir("/"); 867 setsid(); 868 869 /* Make sure environs is set to something sane */ 870 putenv((char *) "HOME=/"); 871 putenv((char *) bb_PATH_root_path); 872 putenv((char *) "SHELL=/bin/sh"); 873 putenv((char *) "USER=root"); /* needed? why? */ 874 875 if (argv[1]) 876 xsetenv("RUNLEVEL", argv[1]); 877 878#if !ENABLE_FEATURE_EXTRA_QUIET 879 /* Hello world */ 880 message(L_CONSOLE | L_LOG, "init started: %s", bb_banner); 881#endif 882 883 /* Make sure there is enough memory to do something useful. */ 884 if (ENABLE_SWAPONOFF) { 885 struct sysinfo info; 886 887 if (sysinfo(&info) == 0 888 && (info.mem_unit ? info.mem_unit : 1) * (long long)info.totalram < 1024*1024 889 ) { 890 message(L_CONSOLE, "Low memory, forcing swapon"); 891 /* swapon -a requires /proc typically */ 892 new_init_action(SYSINIT, "mount -t proc proc /proc", ""); 893 /* Try to turn on swap */ 894 new_init_action(SYSINIT, "swapon -a", ""); 895 run_actions(SYSINIT); /* wait and removing */ 896 } 897 } 898 899 /* Check if we are supposed to be in single user mode */ 900 if (argv[1] 901 && (strcmp(argv[1], "single") == 0 || strcmp(argv[1], "-s") == 0 || LONE_CHAR(argv[1], '1')) 902 ) { 903 /* ??? shouldn't we set RUNLEVEL="b" here? */ 904 /* Start a shell on console */ 905 new_init_action(RESPAWN, bb_default_login_shell, ""); 906 } else { 907 /* Not in single user mode - see what inittab says */ 908 909 /* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined, 910 * then parse_inittab() simply adds in some default 911 * actions(i.e., INIT_SCRIPT and a pair 912 * of "askfirst" shells */ 913 parse_inittab(); 914 } 915 916#if ENABLE_SELINUX 917 if (getenv("SELINUX_INIT") == NULL) { 918 int enforce = 0; 919 920 putenv((char*)"SELINUX_INIT=YES"); 921 if (selinux_init_load_policy(&enforce) == 0) { 922 BB_EXECVP(argv[0], argv); 923 } else if (enforce > 0) { 924 /* SELinux in enforcing mode but load_policy failed */ 925 message(L_CONSOLE, "can't load SELinux Policy. " 926 "Machine is in enforcing mode. Halting now."); 927 exit(EXIT_FAILURE); 928 } 929 } 930#endif 931 932 /* Make the command line just say "init" - thats all, nothing else */ 933 strncpy(argv[0], "init", strlen(argv[0])); 934 /* Wipe argv[1]-argv[N] so they don't clutter the ps listing */ 935 while (*++argv) 936 memset(*argv, 0, strlen(*argv)); 937 938 /* Set up signal handlers */ 939 if (!DEBUG_INIT) { 940 struct sigaction sa; 941 942 bb_signals(0 943 + (1 << SIGUSR1) /* halt */ 944 + (1 << SIGTERM) /* reboot */ 945 + (1 << SIGUSR2) /* poweroff */ 946 , halt_reboot_pwoff); 947 signal(SIGQUIT, restart_handler); /* re-exec another init */ 948 949 /* Stop handler must allow only SIGCONT inside itself */ 950 memset(&sa, 0, sizeof(sa)); 951 sigfillset(&sa.sa_mask); 952 sigdelset(&sa.sa_mask, SIGCONT); 953 sa.sa_handler = stop_handler; 954 /* NB: sa_flags doesn't have SA_RESTART. 955 * It must be able to interrupt wait(). 956 */ 957 sigaction_set(SIGTSTP, &sa); /* pause */ 958 /* Does not work as intended, at least in 2.6.20. 959 * SIGSTOP is simply ignored by init: 960 */ 961 sigaction_set(SIGSTOP, &sa); /* pause */ 962 963 /* SIGINT (Ctrl-Alt-Del) must interrupt wait(), 964 * setting handler without SA_RESTART flag. 965 */ 966 bb_signals_recursive_norestart((1 << SIGINT), record_signo); 967 } 968 969 /* Set up "reread /etc/inittab" handler. 970 * Handler is set up without SA_RESTART, it will interrupt syscalls. 971 */ 972 if (!DEBUG_INIT && ENABLE_FEATURE_USE_INITTAB) 973 bb_signals_recursive_norestart((1 << SIGHUP), record_signo); 974 975 /* Now run everything that needs to be run */ 976 /* First run the sysinit command */ 977 run_actions(SYSINIT); 978 check_delayed_sigs(); 979 /* Next run anything that wants to block */ 980 run_actions(WAIT); 981 check_delayed_sigs(); 982 /* Next run anything to be run only once */ 983 run_actions(ONCE); 984 985 /* Now run the looping stuff for the rest of forever. 986 */ 987 while (1) { 988 int maybe_WNOHANG; 989 990 maybe_WNOHANG = check_delayed_sigs(); 991 992 /* (Re)run the respawn/askfirst stuff */ 993 run_actions(RESPAWN | ASKFIRST); 994 maybe_WNOHANG |= check_delayed_sigs(); 995 996 /* Don't consume all CPU time - sleep a bit */ 997 sleep(1); 998 maybe_WNOHANG |= check_delayed_sigs(); 999 1000 /* Wait for any child process(es) to exit. 1001 * 1002 * If check_delayed_sigs above reported that a signal 1003 * was caught, wait will be nonblocking. This ensures 1004 * that if SIGHUP has reloaded inittab, respawn and askfirst 1005 * actions will not be delayed until next child death. 1006 */ 1007 if (maybe_WNOHANG) 1008 maybe_WNOHANG = WNOHANG; 1009 while (1) { 1010 pid_t wpid; 1011 struct init_action *a; 1012 1013 /* If signals happen _in_ the wait, they interrupt it, 1014 * bb_signals_recursive_norestart set them up that way 1015 */ 1016 wpid = waitpid(-1, NULL, maybe_WNOHANG); 1017 if (wpid <= 0) 1018 break; 1019 1020 a = mark_terminated(wpid); 1021 if (a) { 1022 message(L_LOG, "process '%s' (pid %d) exited. " 1023 "Scheduling for restart.", 1024 a->command, wpid); 1025 } 1026 /* See if anyone else is waiting to be reaped */ 1027 maybe_WNOHANG = WNOHANG; 1028 } 1029 } /* while (1) */ 1030} 1031