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 <paths.h> 14//#include <signal.h> 15//#include <sys/ioctl.h> 16//#include <sys/wait.h> 17#include <sys/reboot.h> 18 19#if ENABLE_FEATURE_INIT_SYSLOG 20# include <sys/syslog.h> 21#endif 22 23#define INIT_BUFFS_SIZE 256 24#define CONSOLE_NAME_SIZE 32 25#define MAXENV 16 /* Number of env. vars */ 26 27#if ENABLE_FEATURE_INIT_COREDUMPS 28/* 29 * When a file named CORE_ENABLE_FLAG_FILE exists, setrlimit is called 30 * before processes are spawned to set core file size as unlimited. 31 * This is for debugging only. Don't use this is production, unless 32 * you want core dumps lying about.... 33 */ 34#define CORE_ENABLE_FLAG_FILE "/.init_enable_core" 35#include <sys/resource.h> 36#endif 37 38#define INITTAB "/etc/inittab" /* inittab file location */ 39#ifndef INIT_SCRIPT 40#define INIT_SCRIPT "/etc/init.d/rcS" /* Default sysinit script. */ 41#endif 42 43/* Allowed init action types */ 44#define SYSINIT 0x001 45#define RESPAWN 0x002 46#define ASKFIRST 0x004 47#define WAIT 0x008 48#define ONCE 0x010 49#define CTRLALTDEL 0x020 50#define SHUTDOWN 0x040 51#define RESTART 0x080 52 53/* A mapping between "inittab" action name strings and action type codes. */ 54struct init_action_type { 55 const char *name; 56 int action; 57}; 58 59static const struct init_action_type actions[] = { 60 {"sysinit", SYSINIT}, 61 {"respawn", RESPAWN}, 62 {"askfirst", ASKFIRST}, 63 {"wait", WAIT}, 64 {"once", ONCE}, 65 {"ctrlaltdel", CTRLALTDEL}, 66 {"shutdown", SHUTDOWN}, 67 {"restart", RESTART}, 68 {0, 0} 69}; 70 71/* Set up a linked list of init_actions, to be read from inittab */ 72struct init_action { 73 struct init_action *next; 74 int action; 75 pid_t pid; 76 char command[INIT_BUFFS_SIZE]; 77 char terminal[CONSOLE_NAME_SIZE]; 78}; 79 80/* Static variables */ 81static struct init_action *init_action_list = NULL; 82 83#if !ENABLE_FEATURE_INIT_SYSLOG 84static const char *log_console = VC_5; 85#endif 86#if !ENABLE_DEBUG_INIT 87static sig_atomic_t got_cont = 0; 88#endif 89 90enum { 91 L_LOG = 0x1, 92 L_CONSOLE = 0x2, 93 94#if ENABLE_FEATURE_EXTRA_QUIET 95 MAYBE_CONSOLE = 0x0, 96#else 97 MAYBE_CONSOLE = L_CONSOLE, 98#endif 99 100#ifndef RB_HALT_SYSTEM 101 RB_HALT_SYSTEM = 0xcdef0123, 102 RB_ENABLE_CAD = 0x89abcdef, 103 RB_DISABLE_CAD = 0, 104 RB_POWER_OFF = 0x4321fedc, 105 RB_AUTOBOOT = 0x01234567, 106#endif 107}; 108 109static const char *const environment[] = { 110 "HOME=/", 111 bb_PATH_root_path, 112 "SHELL=/bin/sh", 113 "USER=root", 114 NULL 115}; 116 117/* Function prototypes */ 118static void delete_init_action(struct init_action *a); 119static int waitfor(const struct init_action *a, pid_t pid); 120#if !ENABLE_DEBUG_INIT 121static void shutdown_signal(int sig); 122#endif 123 124#if !ENABLE_DEBUG_INIT 125static void loop_forever(void) 126{ 127 while (1) 128 sleep(1); 129} 130#endif 131 132/* Print a message to the specified device. 133 * Device may be bitwise-or'd from L_LOG | L_CONSOLE */ 134#if ENABLE_DEBUG_INIT 135#define messageD message 136#else 137#define messageD(...) do {} while (0) 138#endif 139static void message(int device, const char *fmt, ...) 140 __attribute__ ((format(printf, 2, 3))); 141static void message(int device, const char *fmt, ...) 142{ 143#if !ENABLE_FEATURE_INIT_SYSLOG 144 static int log_fd = -1; 145#endif 146 147 va_list arguments; 148 int l; 149 char msg[128]; 150 151 msg[0] = '\r'; 152 va_start(arguments, fmt); 153 vsnprintf(msg + 1, sizeof(msg) - 2, fmt, arguments); 154 va_end(arguments); 155 msg[sizeof(msg) - 2] = '\0'; 156 l = strlen(msg); 157 158#if ENABLE_FEATURE_INIT_SYSLOG 159 /* Log the message to syslogd */ 160 if (device & L_LOG) { 161 /* don't out "\r" */ 162 openlog(applet_name, 0, LOG_DAEMON); 163 syslog(LOG_INFO, "init: %s", msg + 1); 164 closelog(); 165 } 166 msg[l++] = '\n'; 167 msg[l] = '\0'; 168#else 169 msg[l++] = '\n'; 170 msg[l] = '\0'; 171 /* Take full control of the log tty, and never close it. 172 * It's mine, all mine! Muhahahaha! */ 173 if (log_fd < 0) { 174 if (!log_console) { 175 log_fd = 2; 176 } else { 177 log_fd = device_open(log_console, O_WRONLY | O_NONBLOCK | O_NOCTTY); 178 if (log_fd < 0) { 179 bb_error_msg("can't log to %s", log_console); 180 device = L_CONSOLE; 181 } else { 182 fcntl(log_fd, F_SETFD, FD_CLOEXEC); 183 } 184 } 185 } 186 if (device & L_LOG) { 187 full_write(log_fd, msg, l); 188 if (log_fd == 2) 189 return; /* don't print dup messages */ 190 } 191#endif 192 193 if (device & L_CONSOLE) { 194 /* Send console messages to console so people will see them. */ 195 full_write(2, msg, l); 196 } 197} 198 199/* Set terminal settings to reasonable defaults */ 200static void set_sane_term(void) 201{ 202 struct termios tty; 203 204 tcgetattr(STDIN_FILENO, &tty); 205 206 /* set control chars */ 207 tty.c_cc[VINTR] = 3; /* C-c */ 208 tty.c_cc[VQUIT] = 28; /* C-\ */ 209 tty.c_cc[VERASE] = 127; /* C-? */ 210 tty.c_cc[VKILL] = 21; /* C-u */ 211 tty.c_cc[VEOF] = 4; /* C-d */ 212 tty.c_cc[VSTART] = 17; /* C-q */ 213 tty.c_cc[VSTOP] = 19; /* C-s */ 214 tty.c_cc[VSUSP] = 26; /* C-z */ 215 216 /* use line dicipline 0 */ 217 tty.c_line = 0; 218 219 /* Make it be sane */ 220 tty.c_cflag &= CBAUD | CBAUDEX | CSIZE | CSTOPB | PARENB | PARODD; 221 tty.c_cflag |= CREAD | HUPCL | CLOCAL; 222 223 /* input modes */ 224 tty.c_iflag = ICRNL | IXON | IXOFF; 225 226 /* output modes */ 227 tty.c_oflag = OPOST | ONLCR; 228 229 /* local modes */ 230 tty.c_lflag = 231 ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN; 232 233 tcsetattr(STDIN_FILENO, TCSANOW, &tty); 234} 235 236/* From <linux/serial.h> */ 237struct serial_struct { 238 int type; 239 int line; 240 unsigned int port; 241 int irq; 242 int flags; 243 int xmit_fifo_size; 244 int custom_divisor; 245 int baud_base; 246 unsigned short close_delay; 247 char io_type; 248 char reserved_char[1]; 249 int hub6; 250 unsigned short closing_wait; /* time to wait before closing */ 251 unsigned short closing_wait2; /* no longer used... */ 252 unsigned char *iomem_base; 253 unsigned short iomem_reg_shift; 254 unsigned int port_high; 255 unsigned long iomap_base; /* cookie passed into ioremap */ 256 int reserved[1]; 257 /* Paranoia (imagine 64bit kernel overwriting 32bit userspace stack) */ 258 uint32_t bbox_reserved[16]; 259}; 260static void console_init(void) 261{ 262 struct serial_struct sr; 263 char *s; 264 265 s = getenv("CONSOLE"); 266 if (!s) s = getenv("console"); 267 if (s) { 268 int fd = open(s, O_RDWR | O_NONBLOCK | O_NOCTTY); 269 if (fd >= 0) { 270 dup2(fd, 0); 271 dup2(fd, 1); 272 dup2(fd, 2); 273 while (fd > 2) close(fd--); 274 } 275 messageD(L_LOG, "console='%s'", s); 276 } else { 277 /* Make sure fd 0,1,2 are not closed */ 278 bb_sanitize_stdio(); 279 } 280 281 s = getenv("TERM"); 282 if (ioctl(0, TIOCGSERIAL, &sr) == 0) { 283 /* Force the TERM setting to vt102 for serial console -- 284 * if TERM is set to linux (the default) */ 285 if (!s || strcmp(s, "linux") == 0) 286 putenv((char*)"TERM=vt102"); 287#if !ENABLE_FEATURE_INIT_SYSLOG 288 log_console = NULL; 289#endif 290 } else if (!s) 291 putenv((char*)"TERM=linux"); 292} 293 294static void fixup_argv(char **argv) 295{ 296 /* Fix up argv[0] to be certain we claim to be init */ 297 strncpy(argv[0], "init", strlen(argv[0])); 298 299 /* Wipe argv[1]-argv[N] so they don't clutter the ps listing */ 300 while (*++argv) 301 memset(*argv, 0, strlen(*argv)); 302} 303 304/* Open the new terminal device */ 305static void open_stdio_to_tty(const char* tty_name, int fail) 306{ 307 /* empty tty_name means "use init's tty", else... */ 308 if (tty_name[0]) { 309 int fd = device_open(tty_name, O_RDWR); 310 if (fd < 0) { 311 message(L_LOG | L_CONSOLE, "Can't open %s: %s", 312 tty_name, strerror(errno)); 313 if (fail) 314 _exit(1); 315#if !ENABLE_DEBUG_INIT 316 shutdown_signal(SIGUSR1); 317#else 318 _exit(2); 319#endif 320 } else { 321 dup2(fd, 0); 322 dup2(fd, 1); 323 dup2(fd, 2); 324 if (fd > 2) close(fd); 325 } 326 } 327 set_sane_term(); 328} 329 330static pid_t run(const struct init_action *a) 331{ 332 int i; 333 pid_t pid; 334 char *s, *tmpCmd, *cmdpath; 335 char *cmd[INIT_BUFFS_SIZE]; 336 char buf[INIT_BUFFS_SIZE + 6]; /* INIT_BUFFS_SIZE+strlen("exec ")+1 */ 337 sigset_t nmask, omask; 338 339 /* Block sigchild while forking. */ 340 sigemptyset(&nmask); 341 sigaddset(&nmask, SIGCHLD); 342 sigprocmask(SIG_BLOCK, &nmask, &omask); 343 pid = fork(); 344 sigprocmask(SIG_SETMASK, &omask, NULL); 345 346 if (pid) 347 return pid; 348 349 /* Reset signal handlers that were set by the parent process */ 350 signal(SIGUSR1, SIG_DFL); 351 signal(SIGUSR2, SIG_DFL); 352 signal(SIGINT, SIG_DFL); 353 signal(SIGTERM, SIG_DFL); 354 signal(SIGHUP, SIG_DFL); 355 signal(SIGQUIT, SIG_DFL); 356 signal(SIGCONT, SIG_DFL); 357 signal(SIGSTOP, SIG_DFL); 358 signal(SIGTSTP, SIG_DFL); 359 360 /* Create a new session and make ourself the process 361 * group leader */ 362 setsid(); 363 364 /* Open the new terminal device */ 365 open_stdio_to_tty(a->terminal, 1); 366 367 /* If the init Action requires us to wait, then force the 368 * supplied terminal to be the controlling tty. */ 369 if (a->action & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN | RESTART)) { 370 371 /* Now fork off another process to just hang around */ 372 if ((pid = fork()) < 0) { 373 message(L_LOG | L_CONSOLE, "Can't fork"); 374 _exit(1); 375 } 376 377 if (pid > 0) { 378 379 /* We are the parent -- wait till the child is done */ 380 signal(SIGINT, SIG_IGN); 381 signal(SIGTSTP, SIG_IGN); 382 signal(SIGQUIT, SIG_IGN); 383 signal(SIGCHLD, SIG_DFL); 384 385 waitfor(NULL, pid); 386 /* See if stealing the controlling tty back is necessary */ 387 if (tcgetpgrp(0) != getpid()) 388 _exit(0); 389 390 /* Use a temporary process to steal the controlling tty. */ 391 if ((pid = fork()) < 0) { 392 message(L_LOG | L_CONSOLE, "Can't fork"); 393 _exit(1); 394 } 395 if (pid == 0) { 396 setsid(); 397 ioctl(0, TIOCSCTTY, 1); 398 _exit(0); 399 } 400 waitfor(NULL, pid); 401 _exit(0); 402 } 403 404 /* Now fall though to actually execute things */ 405 } 406 407 /* See if any special /bin/sh requiring characters are present */ 408 if (strpbrk(a->command, "~`!$^&*()=|\\{}[];\"'<>?") != NULL) { 409 cmd[0] = (char*)DEFAULT_SHELL; 410 cmd[1] = (char*)"-c"; 411 cmd[2] = strcat(strcpy(buf, "exec "), a->command); 412 cmd[3] = NULL; 413 } else { 414 /* Convert command (char*) into cmd (char**, one word per string) */ 415 strcpy(buf, a->command); 416 s = buf; 417 for (tmpCmd = buf, i = 0; (tmpCmd = strsep(&s, " \t")) != NULL;) { 418 if (*tmpCmd != '\0') { 419 cmd[i] = tmpCmd; 420 i++; 421 } 422 } 423 cmd[i] = NULL; 424 } 425 426 cmdpath = cmd[0]; 427 428 /* 429 * Interactive shells want to see a dash in argv[0]. This 430 * typically is handled by login, argv will be setup this 431 * way if a dash appears at the front of the command path 432 * (like "-/bin/sh"). 433 */ 434 if (*cmdpath == '-') { 435 /* skip over the dash */ 436 ++cmdpath; 437 438 /* find the last component in the command pathname */ 439 s = bb_get_last_path_component(cmdpath); 440 441 /* make a new argv[0] */ 442 if ((cmd[0] = malloc(strlen(s) + 2)) == NULL) { 443 message(L_LOG | L_CONSOLE, bb_msg_memory_exhausted); 444 cmd[0] = cmdpath; 445 } else { 446 cmd[0][0] = '-'; 447 strcpy(cmd[0] + 1, s); 448 } 449#if ENABLE_FEATURE_INIT_SCTTY 450 /* Establish this process as session leader and 451 * (attempt) to make the tty (if any) a controlling tty. 452 */ 453 setsid(); 454 ioctl(0, TIOCSCTTY, 0 /*don't steal it*/); 455#endif 456 } 457 458#if !defined(__UCLIBC__) || defined(__ARCH_HAS_MMU__) 459 if (a->action & ASKFIRST) { 460 static const char press_enter[] ALIGN1 = 461#ifdef CUSTOMIZED_BANNER 462#include CUSTOMIZED_BANNER 463#endif 464 "\nPlease press Enter to activate this console. "; 465 char c; 466 /* 467 * Save memory by not exec-ing anything large (like a shell) 468 * before the user wants it. This is critical if swap is not 469 * enabled and the system has low memory. Generally this will 470 * be run on the second virtual console, and the first will 471 * be allowed to start a shell or whatever an init script 472 * specifies. 473 */ 474 messageD(L_LOG, "waiting for enter to start '%s'" 475 "(pid %d, tty '%s')\n", 476 cmdpath, getpid(), a->terminal); 477 full_write(1, press_enter, sizeof(press_enter) - 1); 478 while (read(0, &c, 1) == 1 && c != '\n') 479 ; 480 } 481#endif 482 /* Log the process name and args */ 483 message(L_LOG, "starting pid %d, tty '%s': '%s'", 484 getpid(), a->terminal, cmdpath); 485 486#if ENABLE_FEATURE_INIT_COREDUMPS 487 { 488 struct stat sb; 489 if (stat(CORE_ENABLE_FLAG_FILE, &sb) == 0) { 490 struct rlimit limit; 491 492 limit.rlim_cur = RLIM_INFINITY; 493 limit.rlim_max = RLIM_INFINITY; 494 setrlimit(RLIMIT_CORE, &limit); 495 } 496 } 497#endif 498 /* Now run it. The new program will take over this PID, 499 * so nothing further in init.c should be run. */ 500 BB_EXECVP(cmdpath, cmd); 501 502 /* We're still here? Some error happened. */ 503 message(L_LOG | L_CONSOLE, "Cannot run '%s': %s", 504 cmdpath, strerror(errno)); 505 _exit(-1); 506} 507 508static int waitfor(const struct init_action *a, pid_t pid) 509{ 510 int runpid; 511 int status, wpid; 512 513 runpid = (NULL == a)? pid : run(a); 514 while (1) { 515 wpid = waitpid(runpid, &status, 0); 516 if (wpid == runpid) 517 break; 518 if (wpid == -1 && errno == ECHILD) { 519 /* we missed its termination */ 520 break; 521 } 522 } 523 return wpid; 524} 525 526/* Run all commands of a particular type */ 527static void run_actions(int action) 528{ 529 struct init_action *a, *tmp; 530 531 for (a = init_action_list; a; a = tmp) { 532 tmp = a->next; 533 if (a->action == action) { 534 /* a->terminal of "" means "init's console" */ 535 if (a->terminal[0] && access(a->terminal, R_OK | W_OK)) { 536 delete_init_action(a); 537 } else if (a->action & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN | RESTART)) { 538 waitfor(a, 0); 539 delete_init_action(a); 540 } else if (a->action & ONCE) { 541 run(a); 542 delete_init_action(a); 543 } else if (a->action & (RESPAWN | ASKFIRST)) { 544 /* Only run stuff with pid==0. If they have 545 * a pid, that means it is still running */ 546 if (a->pid == 0) { 547 a->pid = run(a); 548 } 549 } 550 } 551 } 552} 553 554#if !ENABLE_DEBUG_INIT 555static void init_reboot(unsigned long magic) 556{ 557 pid_t pid; 558 /* We have to fork here, since the kernel calls do_exit(0) in 559 * linux/kernel/sys.c, which can cause the machine to panic when 560 * the init process is killed.... */ 561 pid = vfork(); 562 if (pid == 0) { /* child */ 563 reboot(magic); 564 _exit(0); 565 } 566 waitpid(pid, NULL, 0); 567} 568 569static void shutdown_system(void) 570{ 571 sigset_t block_signals; 572 573 /* run everything to be run at "shutdown". This is done _prior_ 574 * to killing everything, in case people wish to use scripts to 575 * shut things down gracefully... */ 576 run_actions(SHUTDOWN); 577 578 /* first disable all our signals */ 579 sigemptyset(&block_signals); 580 sigaddset(&block_signals, SIGHUP); 581 sigaddset(&block_signals, SIGQUIT); 582 sigaddset(&block_signals, SIGCHLD); 583 sigaddset(&block_signals, SIGUSR1); 584 sigaddset(&block_signals, SIGUSR2); 585 sigaddset(&block_signals, SIGINT); 586 sigaddset(&block_signals, SIGTERM); 587 sigaddset(&block_signals, SIGCONT); 588 sigaddset(&block_signals, SIGSTOP); 589 sigaddset(&block_signals, SIGTSTP); 590 sigprocmask(SIG_BLOCK, &block_signals, NULL); 591 592 message(L_CONSOLE | L_LOG, "The system is going down NOW!"); 593 594 /* Allow Ctrl-Alt-Del to reboot system. */ 595 init_reboot(RB_ENABLE_CAD); 596 597 /* Send signals to every process _except_ pid 1 */ 598 message(L_CONSOLE | L_LOG, "Sending SIG%s to all processes", "TERM"); 599 kill(-1, SIGTERM); 600 sync(); 601 sleep(1); 602 603 message(L_CONSOLE | L_LOG, "Sending SIG%s to all processes", "KILL"); 604 kill(-1, SIGKILL); 605 sync(); 606 sleep(1); 607} 608 609static void exec_signal(int sig ATTRIBUTE_UNUSED) 610{ 611 struct init_action *a, *tmp; 612 sigset_t unblock_signals; 613 614 for (a = init_action_list; a; a = tmp) { 615 tmp = a->next; 616 if (a->action & RESTART) { 617 shutdown_system(); 618 619 /* unblock all signals, blocked in shutdown_system() */ 620 sigemptyset(&unblock_signals); 621 sigaddset(&unblock_signals, SIGHUP); 622 sigaddset(&unblock_signals, SIGQUIT); 623 sigaddset(&unblock_signals, SIGCHLD); 624 sigaddset(&unblock_signals, SIGUSR1); 625 sigaddset(&unblock_signals, SIGUSR2); 626 sigaddset(&unblock_signals, SIGINT); 627 sigaddset(&unblock_signals, SIGTERM); 628 sigaddset(&unblock_signals, SIGCONT); 629 sigaddset(&unblock_signals, SIGSTOP); 630 sigaddset(&unblock_signals, SIGTSTP); 631 sigprocmask(SIG_UNBLOCK, &unblock_signals, NULL); 632 633 /* Open the new terminal device */ 634 open_stdio_to_tty(a->terminal, 0); 635 636 messageD(L_CONSOLE | L_LOG, "Trying to re-exec %s", a->command); 637 BB_EXECLP(a->command, a->command, NULL); 638 639 message(L_CONSOLE | L_LOG, "Cannot run '%s': %s", 640 a->command, strerror(errno)); 641 sleep(2); 642 init_reboot(RB_HALT_SYSTEM); 643 loop_forever(); 644 } 645 } 646} 647 648static void shutdown_signal(int sig) 649{ 650 const char *m; 651 int rb; 652 653 shutdown_system(); 654 655 m = "halt"; 656 rb = RB_HALT_SYSTEM; 657 if (sig == SIGTERM) { 658 m = "reboot"; 659 rb = RB_AUTOBOOT; 660 } else if (sig == SIGUSR2) { 661 m = "poweroff"; 662 rb = RB_POWER_OFF; 663 } 664 message(L_CONSOLE | L_LOG, "Requesting system %s", m); 665 /* allow time for last message to reach serial console */ 666 sleep(2); 667 init_reboot(rb); 668 loop_forever(); 669} 670 671static void ctrlaltdel_signal(int sig ATTRIBUTE_UNUSED) 672{ 673 run_actions(CTRLALTDEL); 674} 675 676/* The SIGSTOP & SIGTSTP handler */ 677static void stop_handler(int sig ATTRIBUTE_UNUSED) 678{ 679 int saved_errno = errno; 680 681 got_cont = 0; 682 while (!got_cont) 683 pause(); 684 got_cont = 0; 685 errno = saved_errno; 686} 687 688/* The SIGCONT handler */ 689static void cont_handler(int sig ATTRIBUTE_UNUSED) 690{ 691 got_cont = 1; 692} 693 694#endif /* !ENABLE_DEBUG_INIT */ 695 696static void new_init_action(int action, const char *command, const char *cons) 697{ 698 struct init_action *new_action, *a, *last; 699 700 if (strcmp(cons, bb_dev_null) == 0 && (action & ASKFIRST)) 701 return; 702 703 /* Append to the end of the list */ 704 for (a = last = init_action_list; a; a = a->next) { 705 /* don't enter action if it's already in the list, 706 * but do overwrite existing actions */ 707 if ((strcmp(a->command, command) == 0) 708 && (strcmp(a->terminal, cons) == 0) 709 ) { 710 a->action = action; 711 return; 712 } 713 last = a; 714 } 715 716 new_action = xzalloc(sizeof(struct init_action)); 717 if (last) { 718 last->next = new_action; 719 } else { 720 init_action_list = new_action; 721 } 722 strcpy(new_action->command, command); 723 new_action->action = action; 724 strcpy(new_action->terminal, cons); 725 messageD(L_LOG | L_CONSOLE, "command='%s' action=%d tty='%s'\n", 726 new_action->command, new_action->action, new_action->terminal); 727} 728 729static void delete_init_action(struct init_action *action) 730{ 731 struct init_action *a, *b = NULL; 732 733 for (a = init_action_list; a; b = a, a = a->next) { 734 if (a == action) { 735 if (b == NULL) { 736 init_action_list = a->next; 737 } else { 738 b->next = a->next; 739 } 740 free(a); 741 break; 742 } 743 } 744} 745 746/* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined, 747 * then parse_inittab() simply adds in some default 748 * actions(i.e., runs INIT_SCRIPT and then starts a pair 749 * of "askfirst" shells). If CONFIG_FEATURE_USE_INITTAB 750 * _is_ defined, but /etc/inittab is missing, this 751 * results in the same set of default behaviors. 752 */ 753static void parse_inittab(void) 754{ 755#if ENABLE_FEATURE_USE_INITTAB 756 FILE *file; 757 char buf[INIT_BUFFS_SIZE], lineAsRead[INIT_BUFFS_SIZE]; 758 char tmpConsole[CONSOLE_NAME_SIZE]; 759 char *id, *runlev, *action, *command, *eol; 760 const struct init_action_type *a = actions; 761 762 file = fopen(INITTAB, "r"); 763 if (file == NULL) { 764 /* No inittab file -- set up some default behavior */ 765#endif 766 /* Reboot on Ctrl-Alt-Del */ 767 new_init_action(CTRLALTDEL, "reboot", ""); 768 /* Umount all filesystems on halt/reboot */ 769 new_init_action(SHUTDOWN, "umount -a -r", ""); 770 /* Swapoff on halt/reboot */ 771 if (ENABLE_SWAPONOFF) new_init_action(SHUTDOWN, "swapoff -a", ""); 772 /* Prepare to restart init when a HUP is received */ 773 new_init_action(RESTART, "init", ""); 774 /* Askfirst shell on tty1-4 */ 775 new_init_action(ASKFIRST, bb_default_login_shell, ""); 776 new_init_action(ASKFIRST, bb_default_login_shell, VC_2); 777 new_init_action(ASKFIRST, bb_default_login_shell, VC_3); 778 new_init_action(ASKFIRST, bb_default_login_shell, VC_4); 779 /* sysinit */ 780 new_init_action(SYSINIT, INIT_SCRIPT, ""); 781 782 return; 783#if ENABLE_FEATURE_USE_INITTAB 784 } 785 786 while (fgets(buf, INIT_BUFFS_SIZE, file) != NULL) { 787 /* Skip leading spaces */ 788 for (id = buf; *id == ' ' || *id == '\t'; id++); 789 790 /* Skip the line if it's a comment */ 791 if (*id == '#' || *id == '\n') 792 continue; 793 794 /* Trim the trailing \n */ 795 eol = strrchr(id, '\n'); 796 if (eol != NULL) 797 *eol = '\0'; 798 799 /* Keep a copy around for posterity's sake (and error msgs) */ 800 strcpy(lineAsRead, buf); 801 802 /* Separate the ID field from the runlevels */ 803 runlev = strchr(id, ':'); 804 if (runlev == NULL || *(runlev + 1) == '\0') { 805 message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead); 806 continue; 807 } else { 808 *runlev = '\0'; 809 ++runlev; 810 } 811 812 /* Separate the runlevels from the action */ 813 action = strchr(runlev, ':'); 814 if (action == NULL || *(action + 1) == '\0') { 815 message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead); 816 continue; 817 } else { 818 *action = '\0'; 819 ++action; 820 } 821 822 /* Separate the action from the command */ 823 command = strchr(action, ':'); 824 if (command == NULL || *(command + 1) == '\0') { 825 message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead); 826 continue; 827 } else { 828 *command = '\0'; 829 ++command; 830 } 831 832 /* Ok, now process it */ 833 for (a = actions; a->name != 0; a++) { 834 if (strcmp(a->name, action) == 0) { 835 if (*id != '\0') { 836 if (strncmp(id, "/dev/", 5) == 0) 837 id += 5; 838 strcpy(tmpConsole, "/dev/"); 839 safe_strncpy(tmpConsole + 5, id, 840 sizeof(tmpConsole) - 5); 841 id = tmpConsole; 842 } 843 new_init_action(a->action, command, id); 844 break; 845 } 846 } 847 if (a->name == 0) { 848 /* Choke on an unknown action */ 849 message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead); 850 } 851 } 852 fclose(file); 853#endif /* FEATURE_USE_INITTAB */ 854} 855 856#if ENABLE_FEATURE_USE_INITTAB 857static void reload_signal(int sig ATTRIBUTE_UNUSED) 858{ 859 struct init_action *a, *tmp; 860 861 message(L_LOG, "reloading /etc/inittab"); 862 863 /* disable old entrys */ 864 for (a = init_action_list; a; a = a->next ) { 865 a->action = ONCE; 866 } 867 868 parse_inittab(); 869 870 /* remove unused entrys */ 871 for (a = init_action_list; a; a = tmp) { 872 tmp = a->next; 873 if ((a->action & (ONCE | SYSINIT | WAIT)) && a->pid == 0) { 874 delete_init_action(a); 875 } 876 } 877 run_actions(RESPAWN); 878} 879#endif /* FEATURE_USE_INITTAB */ 880 881int init_main(int argc, char **argv); 882int init_main(int argc, char **argv) 883{ 884 struct init_action *a; 885 pid_t wpid; 886 887 die_sleep = 30 * 24*60*60; /* if xmalloc will ever die... */ 888 889 if (argc > 1 && !strcmp(argv[1], "-q")) { 890 return kill(1, SIGHUP); 891 } 892#if !ENABLE_DEBUG_INIT 893 /* Expect to be invoked as init with PID=1 or be invoked as linuxrc */ 894 if (getpid() != 1 895 && (!ENABLE_FEATURE_INITRD || !strstr(applet_name, "linuxrc")) 896 ) { 897 bb_show_usage(); 898 } 899 /* Set up sig handlers -- be sure to 900 * clear all of these in run() */ 901 signal(SIGHUP, exec_signal); 902 signal(SIGQUIT, exec_signal); 903 signal(SIGUSR1, shutdown_signal); 904 signal(SIGUSR2, shutdown_signal); 905 signal(SIGINT, ctrlaltdel_signal); 906 signal(SIGTERM, shutdown_signal); 907 signal(SIGCONT, cont_handler); 908 signal(SIGSTOP, stop_handler); 909 signal(SIGTSTP, stop_handler); 910 911 /* Turn off rebooting via CTL-ALT-DEL -- we get a 912 * SIGINT on CAD so we can shut things down gracefully... */ 913 init_reboot(RB_DISABLE_CAD); 914#endif 915 916 917 /* Figure out where the default console should be */ 918 console_init(); 919 set_sane_term(); 920 chdir("/"); 921 setsid(); 922 { 923 const char *const *e; 924 /* Make sure environs is set to something sane */ 925 for (e = environment; *e; e++) 926 putenv((char *) *e); 927 } 928 929 if (argc > 1) setenv("RUNLEVEL", argv[1], 1); 930 931 /* Hello world */ 932 message(MAYBE_CONSOLE | L_LOG, "init started: %s", bb_banner); 933 934 /* Make sure there is enough memory to do something useful. */ 935 if (ENABLE_SWAPONOFF) { 936 struct sysinfo info; 937 938 if (!sysinfo(&info) && 939 (info.mem_unit ? : 1) * (long long)info.totalram < 1024*1024) 940 { 941 message(L_CONSOLE, "Low memory, forcing swapon"); 942 /* swapon -a requires /proc typically */ 943 new_init_action(SYSINIT, "mount -t proc proc /proc", ""); 944 /* Try to turn on swap */ 945 new_init_action(SYSINIT, "swapon -a", ""); 946 run_actions(SYSINIT); /* wait and removing */ 947 } 948 } 949 950 /* Check if we are supposed to be in single user mode */ 951 if (argc > 1 952 && (!strcmp(argv[1], "single") || !strcmp(argv[1], "-s") || LONE_CHAR(argv[1], '1')) 953 ) { 954 /* Start a shell on console */ 955 new_init_action(RESPAWN, bb_default_login_shell, ""); 956 } else { 957 /* Not in single user mode -- see what inittab says */ 958 959 /* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined, 960 * then parse_inittab() simply adds in some default 961 * actions(i.e., runs INIT_SCRIPT and then starts a pair 962 * of "askfirst" shells */ 963 parse_inittab(); 964 } 965 966#if ENABLE_SELINUX 967 if (getenv("SELINUX_INIT") == NULL) { 968 int enforce = 0; 969 970 putenv((char*)"SELINUX_INIT=YES"); 971 if (selinux_init_load_policy(&enforce) == 0) { 972 BB_EXECVP(argv[0], argv); 973 } else if (enforce > 0) { 974 /* SELinux in enforcing mode but load_policy failed */ 975 /* At this point, we probably can't open /dev/console, so log() won't work */ 976 message(L_CONSOLE, "Cannot load SELinux Policy. " 977 "Machine is in enforcing mode. Halting now."); 978 exit(1); 979 } 980 } 981#endif /* CONFIG_SELINUX */ 982 983 /* Make the command line just say "init" -- thats all, nothing else */ 984 fixup_argv(argv); 985 986 /* Now run everything that needs to be run */ 987 988 /* First run the sysinit command */ 989 run_actions(SYSINIT); 990 991 /* Next run anything that wants to block */ 992 run_actions(WAIT); 993 994 /* Next run anything to be run only once */ 995 run_actions(ONCE); 996 997#if ENABLE_FEATURE_USE_INITTAB 998 /* Redefine SIGHUP to reread /etc/inittab */ 999 signal(SIGHUP, reload_signal); 1000#else 1001 signal(SIGHUP, SIG_IGN); 1002#endif /* FEATURE_USE_INITTAB */ 1003 1004 /* Now run the looping stuff for the rest of forever */ 1005 while (1) { 1006 /* run the respawn stuff */ 1007 run_actions(RESPAWN); 1008 1009 /* run the askfirst stuff */ 1010 run_actions(ASKFIRST); 1011 1012 /* Don't consume all CPU time -- sleep a bit */ 1013 sleep(1); 1014 1015 /* Wait for a child process to exit */ 1016 wpid = wait(NULL); 1017 while (wpid > 0) { 1018 /* Find out who died and clean up their corpse */ 1019 for (a = init_action_list; a; a = a->next) { 1020 if (a->pid == wpid) { 1021 /* Set the pid to 0 so that the process gets 1022 * restarted by run_actions() */ 1023 a->pid = 0; 1024 message(L_LOG, "process '%s' (pid %d) exited. " 1025 "Scheduling it for restart.", 1026 a->command, wpid); 1027 } 1028 } 1029 /* see if anyone else is waiting to be reaped */ 1030 wpid = waitpid(-1, NULL, WNOHANG); 1031 } 1032 } 1033} 1034