Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/init/init.c
- Timestamp:
- Feb 25, 2011, 9:26:54 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mindi-busybox/init/init.c
r1765 r2725 7 7 * Adjusted by so many folks, it's impossible to keep track. 8 8 * 9 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.9 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 10 10 */ 11 11 12 //applet:IF_INIT(APPLET(init, _BB_DIR_SBIN, _BB_SUID_DROP)) 13 //applet:IF_FEATURE_INITRD(APPLET_ODDNAME(linuxrc, init, _BB_DIR_ROOT, _BB_SUID_DROP, linuxrc)) 14 15 //kbuild:lib-$(CONFIG_INIT) += init.o 16 17 //config:config INIT 18 //config: bool "init" 19 //config: default y 20 //config: select FEATURE_SYSLOG 21 //config: help 22 //config: init is the first program run when the system boots. 23 //config: 24 //config:config FEATURE_USE_INITTAB 25 //config: bool "Support reading an inittab file" 26 //config: default y 27 //config: depends on INIT 28 //config: help 29 //config: Allow init to read an inittab file when the system boot. 30 //config: 31 //config:config FEATURE_KILL_REMOVED 32 //config: bool "Support killing processes that have been removed from inittab" 33 //config: default n 34 //config: depends on FEATURE_USE_INITTAB 35 //config: help 36 //config: When respawn entries are removed from inittab and a SIGHUP is 37 //config: sent to init, this option will make init kill the processes 38 //config: that have been removed. 39 //config: 40 //config:config FEATURE_KILL_DELAY 41 //config: int "How long to wait between TERM and KILL (0 - send TERM only)" if FEATURE_KILL_REMOVED 42 //config: range 0 1024 43 //config: default 0 44 //config: depends on FEATURE_KILL_REMOVED 45 //config: help 46 //config: With nonzero setting, init sends TERM, forks, child waits N 47 //config: seconds, sends KILL and exits. Setting it too high is unwise 48 //config: (child will hang around for too long and could actually kill 49 //config: the wrong process!) 50 //config: 51 //config:config FEATURE_INIT_SCTTY 52 //config: bool "Run commands with leading dash with controlling tty" 53 //config: default y 54 //config: depends on INIT 55 //config: help 56 //config: If this option is enabled, init will try to give a controlling 57 //config: tty to any command which has leading hyphen (often it's "-/bin/sh"). 58 //config: More precisely, init will do "ioctl(STDIN_FILENO, TIOCSCTTY, 0)". 59 //config: If device attached to STDIN_FILENO can be a ctty but is not yet 60 //config: a ctty for other session, it will become this process' ctty. 61 //config: This is not the traditional init behavour, but is often what you want 62 //config: in an embedded system where the console is only accessed during 63 //config: development or for maintenance. 64 //config: NB: using cttyhack applet may work better. 65 //config: 66 //config:config FEATURE_INIT_SYSLOG 67 //config: bool "Enable init to write to syslog" 68 //config: default y 69 //config: depends on INIT 70 //config: 71 //config:config FEATURE_EXTRA_QUIET 72 //config: bool "Be _extra_ quiet on boot" 73 //config: default y 74 //config: depends on INIT 75 //config: help 76 //config: Prevent init from logging some messages to the console during boot. 77 //config: 78 //config:config FEATURE_INIT_COREDUMPS 79 //config: bool "Support dumping core for child processes (debugging only)" 80 //config: default y 81 //config: depends on INIT 82 //config: help 83 //config: If this option is enabled and the file /.init_enable_core 84 //config: exists, then init will call setrlimit() to allow unlimited 85 //config: core file sizes. If this option is disabled, processes 86 //config: will not generate any core files. 87 //config: 88 //config:config FEATURE_INITRD 89 //config: bool "Support running init from within an initrd (not initramfs)" 90 //config: default y 91 //config: depends on INIT 92 //config: help 93 //config: Legacy support for running init under the old-style initrd. Allows 94 //config: the name linuxrc to act as init, and it doesn't assume init is PID 1. 95 //config: 96 //config: This does not apply to initramfs, which runs /init as PID 1 and 97 //config: requires no special support. 98 //config: 99 //config:config INIT_TERMINAL_TYPE 100 //config: string "Initial terminal type" 101 //config: default "linux" 102 //config: depends on INIT 103 //config: help 104 //config: This is the initial value set by init for the TERM environment 105 //config: variable. This variable is used by programs which make use of 106 //config: extended terminal capabilities. 107 //config: 108 //config: Note that on Linux, init attempts to detect serial terminal and 109 //config: sets TERM to "vt102" if one is found. 110 12 111 #include "libbb.h" 112 #include <syslog.h> 13 113 #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 114 #include <sys/resource.h> 115 #ifdef __linux__ 116 #include <linux/vt.h> 117 #endif 118 #if ENABLE_FEATURE_UTMP 119 # include <utmp.h> /* DEAD_PROCESS */ 120 #endif 121 #include "reboot.h" /* reboot() constants */ 122 123 /* Used only for sanitizing purposes in set_sane_term() below. On systems where 124 * the baud rate is stored in a separate field, we can safely disable them. */ 125 #ifndef CBAUD 126 # define CBAUD 0 127 # define CBAUDEX 0 128 #endif 129 130 /* Was a CONFIG_xxx option. A lot of people were building 131 * not fully functional init by switching it on! */ 132 #define DEBUG_INIT 0 133 134 #define COMMAND_SIZE 256 24 135 #define CONSOLE_NAME_SIZE 32 25 #define MAXENV 16 /* Number of env. vars */ 26 27 #if ENABLE_FEATURE_INIT_COREDUMPS 136 137 /* Default sysinit script. */ 138 #ifndef INIT_SCRIPT 139 #define INIT_SCRIPT "/etc/init.d/rcS" 140 #endif 141 142 /* Each type of actions can appear many times. They will be 143 * handled in order. RESTART is an exception, only 1st is used. 144 */ 145 /* Start these actions first and wait for completion */ 146 #define SYSINIT 0x01 147 /* Start these after SYSINIT and wait for completion */ 148 #define WAIT 0x02 149 /* Start these after WAIT and *dont* wait for completion */ 150 #define ONCE 0x04 28 151 /* 29 * When a file named CORE_ENABLE_FLAG_FILE exists, setrlimit is called30 * before processes are spawned to set core file size as unlimited.31 * This is for debugging only. Don't use this is production, unless32 * you want core dumps lying about....152 * NB: while SYSINIT/WAIT/ONCE are being processed, 153 * SIGHUP ("reread /etc/inittab") will be processed only after 154 * each group of actions. If new inittab adds, say, a SYSINIT action, 155 * it will not be run, since init is already "past SYSINIT stage". 33 156 */ 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. */ 54 struct init_action_type { 55 const char *name; 56 int action; 57 }; 58 59 static 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 */ 157 /* Start these after ONCE are started, restart on exit */ 158 #define RESPAWN 0x08 159 /* Like RESPAWN, but wait for <Enter> to be pressed on tty */ 160 #define ASKFIRST 0x10 161 /* 162 * Start these on SIGINT, and wait for completion. 163 * Then go back to respawning RESPAWN and ASKFIRST actions. 164 * NB: kernel sends SIGINT to us if Ctrl-Alt-Del was pressed. 165 */ 166 #define CTRLALTDEL 0x20 167 /* 168 * Start these before killing all processes in preparation for 169 * running RESTART actions or doing low-level halt/reboot/poweroff 170 * (initiated by SIGUSR1/SIGTERM/SIGUSR2). 171 * Wait for completion before proceeding. 172 */ 173 #define SHUTDOWN 0x40 174 /* 175 * exec() on SIGQUIT. SHUTDOWN actions are started and waited for, 176 * then all processes are killed, then init exec's 1st RESTART action, 177 * replacing itself by it. If no RESTART action specified, 178 * SIGQUIT has no effect. 179 */ 180 #define RESTART 0x80 181 182 183 /* A linked list of init_actions, to be read from inittab */ 72 184 struct init_action { 73 185 struct init_action *next; 74 int action;75 186 pid_t pid; 76 char command[INIT_BUFFS_SIZE];187 uint8_t action_type; 77 188 char terminal[CONSOLE_NAME_SIZE]; 189 char command[COMMAND_SIZE]; 78 190 }; 79 191 80 /* Static variables */81 192 static struct init_action *init_action_list = NULL; 82 193 83 #if !ENABLE_FEATURE_INIT_SYSLOG84 194 static const char *log_console = VC_5; 85 #endif86 #if !ENABLE_DEBUG_INIT87 static sig_atomic_t got_cont = 0;88 #endif89 195 90 196 enum { 91 197 L_LOG = 0x1, 92 198 L_CONSOLE = 0x2, 93 94 #if ENABLE_FEATURE_EXTRA_QUIET95 MAYBE_CONSOLE = 0x0,96 #else97 MAYBE_CONSOLE = L_CONSOLE,98 #endif99 100 #ifndef RB_HALT_SYSTEM101 RB_HALT_SYSTEM = 0xcdef0123, /* FIXME: this overflows enum */102 RB_ENABLE_CAD = 0x89abcdef,103 RB_DISABLE_CAD = 0,104 RB_POWER_OFF = 0x4321fedc,105 RB_AUTOBOOT = 0x01234567,106 #endif107 199 }; 108 200 109 static const char *const environment[] = {110 "HOME=/",111 bb_PATH_root_path,112 "SHELL=/bin/sh",113 "USER=root",114 NULL115 };116 117 /* Function prototypes */118 static void delete_init_action(struct init_action *a);119 static int waitfor(const struct init_action *a, pid_t pid);120 #if !ENABLE_DEBUG_INIT121 static void shutdown_signal(int sig);122 #endif123 124 #if !ENABLE_DEBUG_INIT125 static void loop_forever(void)126 {127 while (1)128 sleep(1);129 }130 #endif131 132 201 /* 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 139 static void message(int device, const char *fmt, ...) 202 * "where" may be bitwise-or'd from L_LOG | L_CONSOLE 203 * NB: careful, we can be called after vfork! 204 */ 205 #define dbg_message(...) do { if (DEBUG_INIT) message(__VA_ARGS__); } while (0) 206 static void message(int where, const char *fmt, ...) 140 207 __attribute__ ((format(printf, 2, 3))); 141 static void message(int device, const char *fmt, ...) 142 { 143 #if !ENABLE_FEATURE_INIT_SYSLOG 144 static int log_fd = -1; 145 #endif 146 208 static void message(int where, const char *fmt, ...) 209 { 147 210 va_list arguments; 148 intl;211 unsigned l; 149 212 char msg[128]; 150 213 151 214 msg[0] = '\r'; 152 215 va_start(arguments, fmt); 153 vsnprintf(msg + 1, sizeof(msg) - 2, fmt, arguments); 216 l = 1 + vsnprintf(msg + 1, sizeof(msg) - 2, fmt, arguments); 217 if (l > sizeof(msg) - 1) 218 l = sizeof(msg) - 1; 154 219 va_end(arguments); 155 msg[sizeof(msg) - 2] = '\0';156 l = strlen(msg);157 220 158 221 #if ENABLE_FEATURE_INIT_SYSLOG 159 /* Log the message to syslogd */160 if ( device & L_LOG) {161 /* don't out "\r"*/222 msg[l] = '\0'; 223 if (where & L_LOG) { 224 /* Log the message to syslogd */ 162 225 openlog(applet_name, 0, LOG_DAEMON); 163 syslog(LOG_INFO, "init: %s", msg + 1); 226 /* don't print "\r" */ 227 syslog(LOG_INFO, "%s", msg + 1); 164 228 closelog(); 165 229 } … … 167 231 msg[l] = '\0'; 168 232 #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; 233 { 234 static int log_fd = -1; 235 236 msg[l++] = '\n'; 237 msg[l] = '\0'; 238 /* Take full control of the log tty, and never close it. 239 * It's mine, all mine! Muhahahaha! */ 240 if (log_fd < 0) { 241 if (!log_console) { 242 log_fd = STDERR_FILENO; 181 243 } else { 182 fcntl(log_fd, F_SETFD, FD_CLOEXEC); 244 log_fd = device_open(log_console, O_WRONLY | O_NONBLOCK | O_NOCTTY); 245 if (log_fd < 0) { 246 bb_error_msg("can't log to %s", log_console); 247 where = L_CONSOLE; 248 } else { 249 close_on_exec_on(log_fd); 250 } 183 251 } 184 252 } 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) {253 if (where & L_LOG) { 254 full_write(log_fd, msg, l); 255 if (log_fd == STDERR_FILENO) 256 return; /* don't print dup messages */ 257 } 258 } 259 #endif 260 261 if (where & L_CONSOLE) { 194 262 /* 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 */ 263 full_write(STDERR_FILENO, msg, l); 264 } 265 } 266 267 static void console_init(void) 268 { 269 #ifdef VT_OPENQRY 270 int vtno; 271 #endif 272 char *s; 273 274 s = getenv("CONSOLE"); 275 if (!s) 276 s = getenv("console"); 277 if (s) { 278 int fd = open(s, O_RDWR | O_NONBLOCK | O_NOCTTY); 279 if (fd >= 0) { 280 dup2(fd, STDIN_FILENO); 281 dup2(fd, STDOUT_FILENO); 282 xmove_fd(fd, STDERR_FILENO); 283 } 284 dbg_message(L_LOG, "console='%s'", s); 285 } else { 286 /* Make sure fd 0,1,2 are not closed 287 * (so that they won't be used by future opens) */ 288 bb_sanitize_stdio(); 289 // Users report problems 290 // /* Make sure init can't be blocked by writing to stderr */ 291 // fcntl(STDERR_FILENO, F_SETFL, fcntl(STDERR_FILENO, F_GETFL) | O_NONBLOCK); 292 } 293 294 s = getenv("TERM"); 295 #ifdef VT_OPENQRY 296 if (ioctl(STDIN_FILENO, VT_OPENQRY, &vtno) != 0) { 297 /* Not a linux terminal, probably serial console. 298 * Force the TERM setting to vt102 299 * if TERM is set to linux (the default) */ 300 if (!s || strcmp(s, "linux") == 0) 301 putenv((char*)"TERM=vt102"); 302 if (!ENABLE_FEATURE_INIT_SYSLOG) 303 log_console = NULL; 304 } else 305 #endif 306 if (!s) 307 putenv((char*)"TERM=" CONFIG_INIT_TERMINAL_TYPE); 308 } 309 310 /* Set terminal settings to reasonable defaults. 311 * NB: careful, we can be called after vfork! */ 200 312 static void set_sane_term(void) 201 313 { … … 214 326 tty.c_cc[VSUSP] = 26; /* C-z */ 215 327 216 /* use line dicipline 0 */ 328 #ifdef __linux__ 329 /* use line discipline 0 */ 217 330 tty.c_line = 0; 331 #endif 218 332 219 333 /* Make it be sane */ 220 tty.c_cflag &= CBAUD | CBAUDEX | CSIZE | CSTOPB | PARENB | PARODD; 334 #ifndef CRTSCTS 335 # define CRTSCTS 0 336 #endif 337 /* added CRTSCTS to fix Debian bug 528560 */ 338 tty.c_cflag &= CBAUD | CBAUDEX | CSIZE | CSTOPB | PARENB | PARODD | CRTSCTS; 221 339 tty.c_cflag |= CREAD | HUPCL | CLOCAL; 222 340 … … 228 346 229 347 /* 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> */ 237 struct 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 }; 260 static 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 294 static 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 */ 305 static void open_stdio_to_tty(const char* tty_name, int fail) 348 tty.c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN; 349 350 tcsetattr_stdin_TCSANOW(&tty); 351 } 352 353 /* Open the new terminal device. 354 * NB: careful, we can be called after vfork! */ 355 static int open_stdio_to_tty(const char* tty_name) 306 356 { 307 357 /* empty tty_name means "use init's tty", else... */ 308 358 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", 359 int fd; 360 361 close(STDIN_FILENO); 362 /* fd can be only < 0 or 0: */ 363 fd = device_open(tty_name, O_RDWR); 364 if (fd) { 365 message(L_LOG | L_CONSOLE, "can't open %s: %s", 312 366 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 } 367 return 0; /* failure */ 368 } 369 dup2(STDIN_FILENO, STDOUT_FILENO); 370 dup2(STDIN_FILENO, STDERR_FILENO); 326 371 } 327 372 set_sane_term(); 328 } 329 330 static 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 } 373 return 1; /* success */ 374 } 375 376 static void reset_sighandlers_and_unblock_sigs(void) 377 { 378 bb_signals(0 379 + (1 << SIGUSR1) 380 + (1 << SIGUSR2) 381 + (1 << SIGTERM) 382 + (1 << SIGQUIT) 383 + (1 << SIGINT) 384 + (1 << SIGHUP) 385 + (1 << SIGTSTP) 386 + (1 << SIGSTOP) 387 , SIG_DFL); 388 sigprocmask_allsigs(SIG_UNBLOCK); 389 } 390 391 /* Wrapper around exec: 392 * Takes string (max COMMAND_SIZE chars). 393 * If chars like '>' detected, execs '[-]/bin/sh -c "exec ......."'. 394 * Otherwise splits words on whitespace, deals with leading dash, 395 * and uses plain exec(). 396 * NB: careful, we can be called after vfork! 397 */ 398 static void init_exec(const char *command) 399 { 400 char *cmd[COMMAND_SIZE / 2]; 401 char buf[COMMAND_SIZE + 6]; /* COMMAND_SIZE+strlen("exec ")+1 */ 402 int dash = (command[0] == '-' /* maybe? && command[1] == '/' */); 406 403 407 404 /* See if any special /bin/sh requiring characters are present */ 408 if (strpbrk(a->command, "~`!$^&*()=|\\{}[];\"'<>?") != NULL) { 409 cmd[0] = (char*)DEFAULT_SHELL; 405 if (strpbrk(command, "~`!$^&*()=|\\{}[];\"'<>?") != NULL) { 406 strcpy(buf, "exec "); 407 strcpy(buf + 5, command + dash); /* excluding "-" */ 408 /* NB: LIBBB_DEFAULT_LOGIN_SHELL define has leading dash */ 409 cmd[0] = (char*)(LIBBB_DEFAULT_LOGIN_SHELL + !dash); 410 410 cmd[1] = (char*)"-c"; 411 cmd[2] = strcat(strcpy(buf, "exec "), a->command);411 cmd[2] = buf; 412 412 cmd[3] = NULL; 413 413 } else { 414 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; 415 char *word, *next; 416 int i = 0; 417 next = strcpy(buf, command); /* including "-" */ 418 while ((word = strsep(&next, " \t")) != NULL) { 419 if (*word != '\0') { /* not two spaces/tabs together? */ 420 cmd[i] = word; 420 421 i++; 421 422 } … … 423 424 cmd[i] = NULL; 424 425 } 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) { 426 /* If we saw leading "-", it is interactive shell. 427 * Try harder to give it a controlling tty. 428 * And skip "-" in actual exec call. */ 429 if (dash) { 430 /* _Attempt_ to make stdin a controlling tty. */ 431 if (ENABLE_FEATURE_INIT_SCTTY) 432 ioctl(STDIN_FILENO, TIOCSCTTY, 0 /*only try, don't steal*/); 433 } 434 BB_EXECVP(cmd[0] + dash, cmd); 435 message(L_LOG | L_CONSOLE, "can't run '%s': %s", cmd[0], strerror(errno)); 436 /* returns if execvp fails */ 437 } 438 439 /* Used only by run_actions */ 440 static pid_t run(const struct init_action *a) 441 { 442 pid_t pid; 443 444 /* Careful: don't be affected by a signal in vforked child */ 445 sigprocmask_allsigs(SIG_BLOCK); 446 if (BB_MMU && (a->action_type & ASKFIRST)) 447 pid = fork(); 448 else 449 pid = vfork(); 450 if (pid < 0) 451 message(L_LOG | L_CONSOLE, "can't fork"); 452 if (pid) { 453 sigprocmask_allsigs(SIG_UNBLOCK); 454 return pid; /* Parent or error */ 455 } 456 457 /* Child */ 458 459 /* Reset signal handlers that were set by the parent process */ 460 reset_sighandlers_and_unblock_sigs(); 461 462 /* Create a new session and make ourself the process group leader */ 463 setsid(); 464 465 /* Open the new terminal device */ 466 if (!open_stdio_to_tty(a->terminal)) 467 _exit(EXIT_FAILURE); 468 469 /* NB: on NOMMU we can't wait for input in child, so 470 * "askfirst" will work the same as "respawn". */ 471 if (BB_MMU && (a->action_type & ASKFIRST)) { 460 472 static const char press_enter[] ALIGN1 = 461 473 #ifdef CUSTOMIZED_BANNER … … 472 484 * specifies. 473 485 */ 474 messageD(L_LOG, "waiting for enter to start '%s'"486 dbg_message(L_LOG, "waiting for enter to start '%s'" 475 487 "(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) {488 a->command, getpid(), a->terminal); 489 full_write(STDOUT_FILENO, press_enter, sizeof(press_enter) - 1); 490 while (safe_read(STDIN_FILENO, &c, 1) == 1 && c != '\n') 491 continue; 492 } 493 494 /* 495 * When a file named /.init_enable_core exists, setrlimit is called 496 * before processes are spawned to set core file size as unlimited. 497 * This is for debugging only. Don't use this is production, unless 498 * you want core dumps lying about.... 499 */ 500 if (ENABLE_FEATURE_INIT_COREDUMPS) { 501 if (access("/.init_enable_core", F_OK) == 0) { 490 502 struct rlimit limit; 491 492 503 limit.rlim_cur = RLIM_INFINITY; 493 504 limit.rlim_max = RLIM_INFINITY; … … 495 506 } 496 507 } 497 #endif 508 509 /* Log the process name and args */ 510 message(L_LOG, "starting pid %d, tty '%s': '%s'", 511 getpid(), a->terminal, a->command); 512 498 513 /* Now run it. The new program will take over this PID, 499 514 * so nothing further in init.c should be run. */ 500 BB_EXECVP(cmdpath, cmd); 501 515 init_exec(a->command); 502 516 /* We're still here? Some error happened. */ 503 message(L_LOG | L_CONSOLE, "Cannot run '%s': %s",504 cmdpath, strerror(errno));505 517 _exit(-1); 506 518 } 507 519 508 static 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); 520 static struct init_action *mark_terminated(pid_t pid) 521 { 522 struct init_action *a; 523 524 if (pid > 0) { 525 for (a = init_action_list; a; a = a->next) { 526 if (a->pid == pid) { 527 a->pid = 0; 528 return a; 529 } 530 } 531 update_utmp(pid, DEAD_PROCESS, /*tty_name:*/ NULL, 532 /*username:*/ NULL, 533 /*hostname:*/ NULL); 534 } 535 return NULL; 536 } 537 538 static void waitfor(pid_t pid) 539 { 540 /* waitfor(run(x)): protect against failed fork inside run() */ 541 if (pid <= 0) 542 return; 543 544 /* Wait for any child (prevent zombies from exiting orphaned processes) 545 * but exit the loop only when specified one has exited. */ 514 546 while (1) { 515 wpid = waitpid(runpid, &status, 0); 516 if (wpid == runpid) 547 pid_t wpid = wait(NULL); 548 mark_terminated(wpid); 549 /* Unsafe. SIGTSTP handler might have wait'ed it already */ 550 /*if (wpid == pid) break;*/ 551 /* More reliable: */ 552 if (kill(pid, 0)) 517 553 break; 518 if (wpid == -1 && errno == ECHILD) { 519 /* we missed its termination */ 554 } 555 } 556 557 /* Run all commands of a particular type */ 558 static void run_actions(int action_type) 559 { 560 struct init_action *a; 561 562 for (a = init_action_list; a; a = a->next) { 563 if (!(a->action_type & action_type)) 564 continue; 565 566 if (a->action_type & (SYSINIT | WAIT | ONCE | CTRLALTDEL | SHUTDOWN)) { 567 pid_t pid = run(a); 568 if (a->action_type & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN)) 569 waitfor(pid); 570 } 571 if (a->action_type & (RESPAWN | ASKFIRST)) { 572 /* Only run stuff with pid == 0. If pid != 0, 573 * it is already running 574 */ 575 if (a->pid == 0) 576 a->pid = run(a); 577 } 578 } 579 } 580 581 static void new_init_action(uint8_t action_type, const char *command, const char *cons) 582 { 583 struct init_action *a, **nextp; 584 585 /* Scenario: 586 * old inittab: 587 * ::shutdown:umount -a -r 588 * ::shutdown:swapoff -a 589 * new inittab: 590 * ::shutdown:swapoff -a 591 * ::shutdown:umount -a -r 592 * On reload, we must ensure entries end up in correct order. 593 * To achieve that, if we find a matching entry, we move it 594 * to the end. 595 */ 596 nextp = &init_action_list; 597 while ((a = *nextp) != NULL) { 598 /* Don't enter action if it's already in the list, 599 * This prevents losing running RESPAWNs. 600 */ 601 if (strcmp(a->command, command) == 0 602 && strcmp(a->terminal, cons) == 0 603 ) { 604 /* Remove from list */ 605 *nextp = a->next; 606 /* Find the end of the list */ 607 while (*nextp != NULL) 608 nextp = &(*nextp)->next; 609 a->next = NULL; 520 610 break; 521 611 } 522 /* FIXME other errors should maybe trigger an error, but allow 523 * the program to continue */ 524 } 525 return wpid; 526 } 527 528 /* Run all commands of a particular type */ 529 static void run_actions(int action) 530 { 531 struct init_action *a, *tmp; 532 533 for (a = init_action_list; a; a = tmp) { 534 tmp = a->next; 535 if (a->action == action) { 536 /* a->terminal of "" means "init's console" */ 537 if (a->terminal[0] && access(a->terminal, R_OK | W_OK)) { 538 delete_init_action(a); 539 } else if (a->action & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN | RESTART)) { 540 waitfor(a, 0); 541 delete_init_action(a); 542 } else if (a->action & ONCE) { 543 run(a); 544 delete_init_action(a); 545 } else if (a->action & (RESPAWN | ASKFIRST)) { 546 /* Only run stuff with pid==0. If they have 547 * a pid, that means it is still running */ 548 if (a->pid == 0) { 549 a->pid = run(a); 550 } 551 } 552 } 553 } 554 } 555 556 #if !ENABLE_DEBUG_INIT 557 static void init_reboot(unsigned long magic) 612 nextp = &a->next; 613 } 614 615 if (!a) 616 a = xzalloc(sizeof(*a)); 617 /* Append to the end of the list */ 618 *nextp = a; 619 a->action_type = action_type; 620 safe_strncpy(a->command, command, sizeof(a->command)); 621 safe_strncpy(a->terminal, cons, sizeof(a->terminal)); 622 dbg_message(L_LOG | L_CONSOLE, "command='%s' action=%d tty='%s'\n", 623 a->command, a->action_type, a->terminal); 624 } 625 626 /* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined, 627 * then parse_inittab() simply adds in some default 628 * actions(i.e., runs INIT_SCRIPT and then starts a pair 629 * of "askfirst" shells). If CONFIG_FEATURE_USE_INITTAB 630 * _is_ defined, but /etc/inittab is missing, this 631 * results in the same set of default behaviors. 632 */ 633 static void parse_inittab(void) 634 { 635 #if ENABLE_FEATURE_USE_INITTAB 636 char *token[4]; 637 parser_t *parser = config_open2("/etc/inittab", fopen_for_read); 638 639 if (parser == NULL) 640 #endif 641 { 642 /* No inittab file - set up some default behavior */ 643 /* Reboot on Ctrl-Alt-Del */ 644 new_init_action(CTRLALTDEL, "reboot", ""); 645 /* Umount all filesystems on halt/reboot */ 646 new_init_action(SHUTDOWN, "umount -a -r", ""); 647 /* Swapoff on halt/reboot */ 648 if (ENABLE_SWAPONOFF) 649 new_init_action(SHUTDOWN, "swapoff -a", ""); 650 /* Prepare to restart init when a QUIT is received */ 651 new_init_action(RESTART, "init", ""); 652 /* Askfirst shell on tty1-4 */ 653 new_init_action(ASKFIRST, bb_default_login_shell, ""); 654 //TODO: VC_1 instead of ""? "" is console -> ctty problems -> angry users 655 new_init_action(ASKFIRST, bb_default_login_shell, VC_2); 656 new_init_action(ASKFIRST, bb_default_login_shell, VC_3); 657 new_init_action(ASKFIRST, bb_default_login_shell, VC_4); 658 /* sysinit */ 659 new_init_action(SYSINIT, INIT_SCRIPT, ""); 660 return; 661 } 662 663 #if ENABLE_FEATURE_USE_INITTAB 664 /* optional_tty:ignored_runlevel:action:command 665 * Delims are not to be collapsed and need exactly 4 tokens 666 */ 667 while (config_read(parser, token, 4, 0, "#:", 668 PARSE_NORMAL & ~(PARSE_TRIM | PARSE_COLLAPSE))) { 669 /* order must correspond to SYSINIT..RESTART constants */ 670 static const char actions[] ALIGN1 = 671 "sysinit\0""wait\0""once\0""respawn\0""askfirst\0" 672 "ctrlaltdel\0""shutdown\0""restart\0"; 673 int action; 674 char *tty = token[0]; 675 676 if (!token[3]) /* less than 4 tokens */ 677 goto bad_entry; 678 action = index_in_strings(actions, token[2]); 679 if (action < 0 || !token[3][0]) /* token[3]: command */ 680 goto bad_entry; 681 /* turn .*TTY -> /dev/TTY */ 682 if (tty[0]) { 683 tty = concat_path_file("/dev/", skip_dev_pfx(tty)); 684 } 685 new_init_action(1 << action, token[3], tty); 686 if (tty[0]) 687 free(tty); 688 continue; 689 bad_entry: 690 message(L_LOG | L_CONSOLE, "Bad inittab entry at line %d", 691 parser->lineno); 692 } 693 config_close(parser); 694 #endif 695 } 696 697 static void pause_and_low_level_reboot(unsigned magic) NORETURN; 698 static void pause_and_low_level_reboot(unsigned magic) 558 699 { 559 700 pid_t pid; 560 /* We have to fork here, since the kernel calls do_exit(0) in 561 * linux/kernel/sys.c, which can cause the machine to panic when 562 * the init process is killed.... */ 701 702 /* Allow time for last message to reach serial console, etc */ 703 sleep(1); 704 705 /* We have to fork here, since the kernel calls do_exit(EXIT_SUCCESS) 706 * in linux/kernel/sys.c, which can cause the machine to panic when 707 * the init process exits... */ 563 708 pid = vfork(); 564 709 if (pid == 0) { /* child */ 565 710 reboot(magic); 566 _exit(0); 567 } 568 waitpid(pid, NULL, 0); 569 } 570 571 static void shutdown_system(void) 572 { 573 sigset_t block_signals; 574 575 /* run everything to be run at "shutdown". This is done _prior_ 711 _exit(EXIT_SUCCESS); 712 } 713 while (1) 714 sleep(1); 715 } 716 717 static void run_shutdown_and_kill_processes(void) 718 { 719 /* Run everything to be run at "shutdown". This is done _prior_ 576 720 * to killing everything, in case people wish to use scripts to 577 721 * shut things down gracefully... */ 578 722 run_actions(SHUTDOWN); 579 723 580 /* first disable all our signals */581 sigemptyset(&block_signals);582 sigaddset(&block_signals, SIGHUP);583 sigaddset(&block_signals, SIGQUIT);584 sigaddset(&block_signals, SIGCHLD);585 sigaddset(&block_signals, SIGUSR1);586 sigaddset(&block_signals, SIGUSR2);587 sigaddset(&block_signals, SIGINT);588 sigaddset(&block_signals, SIGTERM);589 sigaddset(&block_signals, SIGCONT);590 sigaddset(&block_signals, SIGSTOP);591 sigaddset(&block_signals, SIGTSTP);592 sigprocmask(SIG_BLOCK, &block_signals, NULL);593 594 724 message(L_CONSOLE | L_LOG, "The system is going down NOW!"); 595 725 596 /* Allow Ctrl-Alt-Del to reboot system. */597 init_reboot(RB_ENABLE_CAD);598 599 726 /* Send signals to every process _except_ pid 1 */ 600 message(L_CONSOLE | L_LOG, "Sending SIG%s to all processes", "TERM");601 727 kill(-1, SIGTERM); 728 message(L_CONSOLE | L_LOG, "Sent SIG%s to all processes", "TERM"); 602 729 sync(); 603 730 sleep(1); 604 731 605 message(L_CONSOLE | L_LOG, "Sending SIG%s to all processes", "KILL");606 732 kill(-1, SIGKILL); 733 message(L_CONSOLE, "Sent SIG%s to all processes", "KILL"); 607 734 sync(); 608 sleep(1); 609 } 610 611 static void exec_signal(int sig ATTRIBUTE_UNUSED) 612 { 613 struct init_action *a, *tmp; 614 sigset_t unblock_signals; 615 616 for (a = init_action_list; a; a = tmp) { 617 tmp = a->next; 618 if (a->action & RESTART) { 619 shutdown_system(); 620 621 /* unblock all signals, blocked in shutdown_system() */ 622 sigemptyset(&unblock_signals); 623 sigaddset(&unblock_signals, SIGHUP); 624 sigaddset(&unblock_signals, SIGQUIT); 625 sigaddset(&unblock_signals, SIGCHLD); 626 sigaddset(&unblock_signals, SIGUSR1); 627 sigaddset(&unblock_signals, SIGUSR2); 628 sigaddset(&unblock_signals, SIGINT); 629 sigaddset(&unblock_signals, SIGTERM); 630 sigaddset(&unblock_signals, SIGCONT); 631 sigaddset(&unblock_signals, SIGSTOP); 632 sigaddset(&unblock_signals, SIGTSTP); 633 sigprocmask(SIG_UNBLOCK, &unblock_signals, NULL); 634 635 /* Open the new terminal device */ 636 open_stdio_to_tty(a->terminal, 0); 637 638 messageD(L_CONSOLE | L_LOG, "Trying to re-exec %s", a->command); 639 BB_EXECLP(a->command, a->command, NULL); 640 641 message(L_CONSOLE | L_LOG, "Cannot run '%s': %s", 642 a->command, strerror(errno)); 643 sleep(2); 644 init_reboot(RB_HALT_SYSTEM); 645 loop_forever(); 646 } 647 } 648 } 649 650 static void shutdown_signal(int sig) 735 /*sleep(1); - callers take care about making a pause */ 736 } 737 738 /* Signal handling by init: 739 * 740 * For process with PID==1, on entry kernel sets all signals to SIG_DFL 741 * and unmasks all signals. However, for process with PID==1, 742 * default action (SIG_DFL) on any signal is to ignore it, 743 * even for special signals SIGKILL and SIGCONT. 744 * Also, any signal can be caught or blocked. 745 * (but SIGSTOP is still handled specially, at least in 2.6.20) 746 * 747 * We install two kinds of handlers, "immediate" and "delayed". 748 * 749 * Immediate handlers execute at any time, even while, say, sysinit 750 * is running. 751 * 752 * Delayed handlers just set a flag variable. The variable is checked 753 * in the main loop and acted upon. 754 * 755 * halt/poweroff/reboot and restart have immediate handlers. 756 * They only traverse linked list of struct action's, never modify it, 757 * this should be safe to do even in signal handler. Also they 758 * never return. 759 * 760 * SIGSTOP and SIGTSTP have immediate handlers. They just wait 761 * for SIGCONT to happen. 762 * 763 * SIGHUP has a delayed handler, because modifying linked list 764 * of struct action's from a signal handler while it is manipulated 765 * by the program may be disastrous. 766 * 767 * Ctrl-Alt-Del has a delayed handler. Not a must, but allowing 768 * it to happen even somewhere inside "sysinit" would be a bit awkward. 769 * 770 * There is a tiny probability that SIGHUP and Ctrl-Alt-Del will collide 771 * and only one will be remembered and acted upon. 772 */ 773 774 /* The SIGUSR[12]/SIGTERM handler */ 775 static void halt_reboot_pwoff(int sig) NORETURN; 776 static void halt_reboot_pwoff(int sig) 651 777 { 652 778 const char *m; 653 int rb; 654 655 shutdown_system(); 779 unsigned rb; 780 781 /* We may call run() and it unmasks signals, 782 * including the one masked inside this signal handler. 783 * Testcase which would start multiple reboot scripts: 784 * while true; do reboot; done 785 * Preventing it: 786 */ 787 reset_sighandlers_and_unblock_sigs(); 788 789 run_shutdown_and_kill_processes(); 656 790 657 791 m = "halt"; … … 664 798 rb = RB_POWER_OFF; 665 799 } 666 message(L_CONSOLE | L_LOG, "Requesting system %s", m); 667 /* allow time for last message to reach serial console */ 668 sleep(2); 669 init_reboot(rb); 670 loop_forever(); 671 } 672 673 static void ctrlaltdel_signal(int sig ATTRIBUTE_UNUSED) 674 { 675 run_actions(CTRLALTDEL); 676 } 677 678 /* The SIGSTOP & SIGTSTP handler */ 679 static void stop_handler(int sig ATTRIBUTE_UNUSED) 680 { 681 int saved_errno = errno; 682 683 got_cont = 0; 684 while (!got_cont) 685 pause(); 686 got_cont = 0; 800 message(L_CONSOLE, "Requesting system %s", m); 801 pause_and_low_level_reboot(rb); 802 /* not reached */ 803 } 804 805 /* Handler for QUIT - exec "restart" action, 806 * else (no such action defined) do nothing */ 807 static void restart_handler(int sig UNUSED_PARAM) 808 { 809 struct init_action *a; 810 811 for (a = init_action_list; a; a = a->next) { 812 if (!(a->action_type & RESTART)) 813 continue; 814 815 /* Starting from here, we won't return. 816 * Thus don't need to worry about preserving errno 817 * and such. 818 */ 819 820 reset_sighandlers_and_unblock_sigs(); 821 822 run_shutdown_and_kill_processes(); 823 824 #ifdef RB_ENABLE_CAD 825 /* Allow Ctrl-Alt-Del to reboot the system. 826 * This is how kernel sets it up for init, we follow suit. 827 */ 828 reboot(RB_ENABLE_CAD); /* misnomer */ 829 #endif 830 831 if (open_stdio_to_tty(a->terminal)) { 832 dbg_message(L_CONSOLE, "Trying to re-exec %s", a->command); 833 /* Theoretically should be safe. 834 * But in practice, kernel bugs may leave 835 * unkillable processes, and wait() may block forever. 836 * Oh well. Hoping "new" init won't be too surprised 837 * by having children it didn't create. 838 */ 839 //while (wait(NULL) > 0) 840 // continue; 841 init_exec(a->command); 842 } 843 /* Open or exec failed */ 844 pause_and_low_level_reboot(RB_HALT_SYSTEM); 845 /* not reached */ 846 } 847 } 848 849 /* The SIGSTOP/SIGTSTP handler 850 * NB: inside it, all signals except SIGCONT are masked 851 * via appropriate setup in sigaction(). 852 */ 853 static void stop_handler(int sig UNUSED_PARAM) 854 { 855 smallint saved_bb_got_signal; 856 int saved_errno; 857 858 saved_bb_got_signal = bb_got_signal; 859 saved_errno = errno; 860 signal(SIGCONT, record_signo); 861 862 while (1) { 863 pid_t wpid; 864 865 if (bb_got_signal == SIGCONT) 866 break; 867 /* NB: this can accidentally wait() for a process 868 * which we waitfor() elsewhere! waitfor() must have 869 * code which is resilient against this. 870 */ 871 wpid = wait_any_nohang(NULL); 872 mark_terminated(wpid); 873 sleep(1); 874 } 875 876 signal(SIGCONT, SIG_DFL); 687 877 errno = saved_errno; 688 } 689 690 /* The SIGCONT handler */ 691 static void cont_handler(int sig ATTRIBUTE_UNUSED) 692 { 693 got_cont = 1; 694 } 695 696 #endif /* !ENABLE_DEBUG_INIT */ 697 698 static void new_init_action(int action, const char *command, const char *cons) 699 { 700 struct init_action *new_action, *a, *last; 701 702 if (strcmp(cons, bb_dev_null) == 0 && (action & ASKFIRST)) 703 return; 704 705 /* Append to the end of the list */ 706 for (a = last = init_action_list; a; a = a->next) { 707 /* don't enter action if it's already in the list, 708 * but do overwrite existing actions */ 709 if ((strcmp(a->command, command) == 0) 710 && (strcmp(a->terminal, cons) == 0) 878 bb_got_signal = saved_bb_got_signal; 879 } 880 881 #if ENABLE_FEATURE_USE_INITTAB 882 static void reload_inittab(void) 883 { 884 struct init_action *a, **nextp; 885 886 message(L_LOG, "reloading /etc/inittab"); 887 888 /* Disable old entries */ 889 for (a = init_action_list; a; a = a->next) 890 a->action_type = 0; 891 892 /* Append new entries, or modify existing entries 893 * (incl. setting a->action_type) if cmd and device name 894 * match new ones. End result: only entries with 895 * a->action_type == 0 are stale. 896 */ 897 parse_inittab(); 898 899 #if ENABLE_FEATURE_KILL_REMOVED 900 /* Kill stale entries */ 901 /* Be nice and send SIGTERM first */ 902 for (a = init_action_list; a; a = a->next) 903 if (a->action_type == 0 && a->pid != 0) 904 kill(a->pid, SIGTERM); 905 if (CONFIG_FEATURE_KILL_DELAY) { 906 /* NB: parent will wait in NOMMU case */ 907 if ((BB_MMU ? fork() : vfork()) == 0) { /* child */ 908 sleep(CONFIG_FEATURE_KILL_DELAY); 909 for (a = init_action_list; a; a = a->next) 910 if (a->action_type == 0 && a->pid != 0) 911 kill(a->pid, SIGKILL); 912 _exit(EXIT_SUCCESS); 913 } 914 } 915 #endif 916 917 /* Remove stale entries and SYSINIT entries. 918 * We never rerun SYSINIT entries anyway, 919 * removing them too saves a few bytes */ 920 nextp = &init_action_list; 921 while ((a = *nextp) != NULL) { 922 if ((a->action_type & ~SYSINIT) == 0) { 923 *nextp = a->next; 924 free(a); 925 } else { 926 nextp = &a->next; 927 } 928 } 929 930 /* Not needed: */ 931 /* run_actions(RESPAWN | ASKFIRST); */ 932 /* - we return to main loop, which does this automagically */ 933 } 934 #endif 935 936 static int check_delayed_sigs(void) 937 { 938 int sigs_seen = 0; 939 940 while (1) { 941 smallint sig = bb_got_signal; 942 943 if (!sig) 944 return sigs_seen; 945 bb_got_signal = 0; 946 sigs_seen = 1; 947 #if ENABLE_FEATURE_USE_INITTAB 948 if (sig == SIGHUP) 949 reload_inittab(); 950 #endif 951 if (sig == SIGINT) 952 run_actions(CTRLALTDEL); 953 } 954 } 955 956 int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 957 int init_main(int argc UNUSED_PARAM, char **argv) 958 { 959 if (argv[1] && strcmp(argv[1], "-q") == 0) { 960 return kill(1, SIGHUP); 961 } 962 963 if (!DEBUG_INIT) { 964 /* Expect to be invoked as init with PID=1 or be invoked as linuxrc */ 965 if (getpid() != 1 966 && (!ENABLE_FEATURE_INITRD || applet_name[0] != 'l') /* not linuxrc? */ 711 967 ) { 712 a->action = action; 713 return; 714 } 715 last = a; 716 } 717 718 new_action = xzalloc(sizeof(struct init_action)); 719 if (last) { 720 last->next = new_action; 721 } else { 722 init_action_list = new_action; 723 } 724 strcpy(new_action->command, command); 725 new_action->action = action; 726 strcpy(new_action->terminal, cons); 727 messageD(L_LOG | L_CONSOLE, "command='%s' action=%d tty='%s'\n", 728 new_action->command, new_action->action, new_action->terminal); 729 } 730 731 static void delete_init_action(struct init_action *action) 732 { 733 struct init_action *a, *b = NULL; 734 735 for (a = init_action_list; a; b = a, a = a->next) { 736 if (a == action) { 737 if (b == NULL) { 738 init_action_list = a->next; 739 } else { 740 b->next = a->next; 741 } 742 free(a); 743 break; 744 } 745 } 746 } 747 748 /* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined, 749 * then parse_inittab() simply adds in some default 750 * actions(i.e., runs INIT_SCRIPT and then starts a pair 751 * of "askfirst" shells). If CONFIG_FEATURE_USE_INITTAB 752 * _is_ defined, but /etc/inittab is missing, this 753 * results in the same set of default behaviors. 754 */ 755 static void parse_inittab(void) 756 { 757 #if ENABLE_FEATURE_USE_INITTAB 758 FILE *file; 759 char buf[INIT_BUFFS_SIZE], lineAsRead[INIT_BUFFS_SIZE]; 760 char tmpConsole[CONSOLE_NAME_SIZE]; 761 char *id, *runlev, *action, *command, *eol; 762 const struct init_action_type *a = actions; 763 764 file = fopen(INITTAB, "r"); 765 if (file == NULL) { 766 /* No inittab file -- set up some default behavior */ 767 #endif 768 /* Reboot on Ctrl-Alt-Del */ 769 new_init_action(CTRLALTDEL, "reboot", ""); 770 /* Umount all filesystems on halt/reboot */ 771 new_init_action(SHUTDOWN, "umount -a -r", ""); 772 /* Swapoff on halt/reboot */ 773 if (ENABLE_SWAPONOFF) new_init_action(SHUTDOWN, "swapoff -a", ""); 774 /* Prepare to restart init when a HUP is received */ 775 new_init_action(RESTART, "init", ""); 776 /* Askfirst shell on tty1-4 */ 777 new_init_action(ASKFIRST, bb_default_login_shell, ""); 778 new_init_action(ASKFIRST, bb_default_login_shell, VC_2); 779 new_init_action(ASKFIRST, bb_default_login_shell, VC_3); 780 new_init_action(ASKFIRST, bb_default_login_shell, VC_4); 781 /* sysinit */ 782 new_init_action(SYSINIT, INIT_SCRIPT, ""); 783 784 return; 785 #if ENABLE_FEATURE_USE_INITTAB 786 } 787 788 while (fgets(buf, INIT_BUFFS_SIZE, file) != NULL) { 789 /* Skip leading spaces */ 790 for (id = buf; *id == ' ' || *id == '\t'; id++); 791 792 /* Skip the line if it's a comment */ 793 if (*id == '#' || *id == '\n') 794 continue; 795 796 /* Trim the trailing \n */ 797 //XXX: chomp() ? 798 eol = strrchr(id, '\n'); 799 if (eol != NULL) 800 *eol = '\0'; 801 802 /* Keep a copy around for posterity's sake (and error msgs) */ 803 strcpy(lineAsRead, buf); 804 805 /* Separate the ID field from the runlevels */ 806 runlev = strchr(id, ':'); 807 if (runlev == NULL || *(runlev + 1) == '\0') { 808 message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead); 809 continue; 810 } else { 811 *runlev = '\0'; 812 ++runlev; 813 } 814 815 /* Separate the runlevels from the action */ 816 action = strchr(runlev, ':'); 817 if (action == NULL || *(action + 1) == '\0') { 818 message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead); 819 continue; 820 } else { 821 *action = '\0'; 822 ++action; 823 } 824 825 /* Separate the action from the command */ 826 command = strchr(action, ':'); 827 if (command == NULL || *(command + 1) == '\0') { 828 message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead); 829 continue; 830 } else { 831 *command = '\0'; 832 ++command; 833 } 834 835 /* Ok, now process it */ 836 for (a = actions; a->name != 0; a++) { 837 if (strcmp(a->name, action) == 0) { 838 if (*id != '\0') { 839 if (strncmp(id, "/dev/", 5) == 0) 840 id += 5; 841 strcpy(tmpConsole, "/dev/"); 842 safe_strncpy(tmpConsole + 5, id, 843 sizeof(tmpConsole) - 5); 844 id = tmpConsole; 845 } 846 new_init_action(a->action, command, id); 847 break; 848 } 849 } 850 if (a->name == 0) { 851 /* Choke on an unknown action */ 852 message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead); 853 } 854 } 855 fclose(file); 856 #endif /* FEATURE_USE_INITTAB */ 857 } 858 859 #if ENABLE_FEATURE_USE_INITTAB 860 static void reload_signal(int sig ATTRIBUTE_UNUSED) 861 { 862 struct init_action *a, *tmp; 863 864 message(L_LOG, "reloading /etc/inittab"); 865 866 /* disable old entrys */ 867 for (a = init_action_list; a; a = a->next ) { 868 a->action = ONCE; 869 } 870 871 parse_inittab(); 872 873 /* remove unused entrys */ 874 for (a = init_action_list; a; a = tmp) { 875 tmp = a->next; 876 if ((a->action & (ONCE | SYSINIT | WAIT)) && a->pid == 0) { 877 delete_init_action(a); 878 } 879 } 880 run_actions(RESPAWN); 881 } 882 #endif /* FEATURE_USE_INITTAB */ 883 884 int init_main(int argc, char **argv); 885 int init_main(int argc, char **argv) 886 { 887 struct init_action *a; 888 pid_t wpid; 889 890 die_sleep = 30 * 24*60*60; /* if xmalloc will ever die... */ 891 892 if (argc > 1 && !strcmp(argv[1], "-q")) { 893 return kill(1, SIGHUP); 894 } 895 #if !ENABLE_DEBUG_INIT 896 /* Expect to be invoked as init with PID=1 or be invoked as linuxrc */ 897 if (getpid() != 1 898 && (!ENABLE_FEATURE_INITRD || !strstr(applet_name, "linuxrc")) 899 ) { 900 bb_show_usage(); 901 } 902 /* Set up sig handlers -- be sure to 903 * clear all of these in run() */ 904 signal(SIGHUP, exec_signal); 905 signal(SIGQUIT, exec_signal); 906 signal(SIGUSR1, shutdown_signal); 907 signal(SIGUSR2, shutdown_signal); 908 signal(SIGINT, ctrlaltdel_signal); 909 signal(SIGTERM, shutdown_signal); 910 signal(SIGCONT, cont_handler); 911 signal(SIGSTOP, stop_handler); 912 signal(SIGTSTP, stop_handler); 913 914 /* Turn off rebooting via CTL-ALT-DEL -- we get a 915 * SIGINT on CAD so we can shut things down gracefully... */ 916 init_reboot(RB_DISABLE_CAD); 917 #endif 918 968 bb_error_msg_and_die("must be run as PID 1"); 969 } 970 #ifdef RB_DISABLE_CAD 971 /* Turn off rebooting via CTL-ALT-DEL - we get a 972 * SIGINT on CAD so we can shut things down gracefully... */ 973 reboot(RB_DISABLE_CAD); /* misnomer */ 974 #endif 975 } 976 977 /* If, say, xmalloc would ever die, we don't want to oops kernel 978 * by exiting. 979 * NB: we set die_sleep *after* PID 1 check and bb_show_usage. 980 * Otherwise, for example, "init u" ("please rexec yourself" 981 * command for sysvinit) will show help text (which isn't too bad), 982 * *and sleep forever* (which is bad!) 983 */ 984 die_sleep = 30 * 24*60*60; 919 985 920 986 /* Figure out where the default console should be */ 921 987 console_init(); 922 988 set_sane_term(); 923 chdir("/");989 xchdir("/"); 924 990 setsid(); 925 { 926 const char *const *e; 927 /* Make sure environs is set to something sane */ 928 for (e = environment; *e; e++) 929 putenv((char *) *e); 930 } 931 932 if (argc > 1) setenv("RUNLEVEL", argv[1], 1); 933 991 992 /* Make sure environs is set to something sane */ 993 putenv((char *) "HOME=/"); 994 putenv((char *) bb_PATH_root_path); 995 putenv((char *) "SHELL=/bin/sh"); 996 putenv((char *) "USER=root"); /* needed? why? */ 997 998 if (argv[1]) 999 xsetenv("RUNLEVEL", argv[1]); 1000 1001 #if !ENABLE_FEATURE_EXTRA_QUIET 934 1002 /* Hello world */ 935 message(MAYBE_CONSOLE | L_LOG, "init started: %s", bb_banner); 936 1003 message(L_CONSOLE | L_LOG, "init started: %s", bb_banner); 1004 #endif 1005 1006 /* struct sysinfo is linux-specific */ 1007 #ifdef __linux__ 937 1008 /* Make sure there is enough memory to do something useful. */ 938 1009 if (ENABLE_SWAPONOFF) { 939 1010 struct sysinfo info; 940 1011 941 if ( !sysinfo(&info) &&942 (info.mem_unit ? : 1) * (long long)info.totalram < 1024*1024)943 {1012 if (sysinfo(&info) == 0 1013 && (info.mem_unit ? info.mem_unit : 1) * (long long)info.totalram < 1024*1024 1014 ) { 944 1015 message(L_CONSOLE, "Low memory, forcing swapon"); 945 1016 /* swapon -a requires /proc typically */ … … 950 1021 } 951 1022 } 1023 #endif 952 1024 953 1025 /* Check if we are supposed to be in single user mode */ 954 if (arg c > 1955 && ( !strcmp(argv[1], "single") || !strcmp(argv[1], "-s")|| LONE_CHAR(argv[1], '1'))1026 if (argv[1] 1027 && (strcmp(argv[1], "single") == 0 || strcmp(argv[1], "-s") == 0 || LONE_CHAR(argv[1], '1')) 956 1028 ) { 1029 /* ??? shouldn't we set RUNLEVEL="b" here? */ 957 1030 /* Start a shell on console */ 958 1031 new_init_action(RESPAWN, bb_default_login_shell, ""); 959 1032 } else { 960 /* Not in single user mode - -see what inittab says */1033 /* Not in single user mode - see what inittab says */ 961 1034 962 1035 /* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined, 963 1036 * then parse_inittab() simply adds in some default 964 * actions(i.e., runs INIT_SCRIPT and then startsa pair1037 * actions(i.e., INIT_SCRIPT and a pair 965 1038 * of "askfirst" shells */ 966 1039 parse_inittab(); … … 976 1049 } else if (enforce > 0) { 977 1050 /* SELinux in enforcing mode but load_policy failed */ 978 /* At this point, we probably can't open /dev/console, so log() won't work */ 979 message(L_CONSOLE, "Cannot load SELinux Policy. " 1051 message(L_CONSOLE, "can't load SELinux Policy. " 980 1052 "Machine is in enforcing mode. Halting now."); 981 exit(1); 982 } 983 } 984 #endif /* CONFIG_SELINUX */ 985 986 /* Make the command line just say "init" -- thats all, nothing else */ 987 fixup_argv(argv); 1053 return EXIT_FAILURE; 1054 } 1055 } 1056 #endif 1057 1058 /* Make the command line just say "init" - thats all, nothing else */ 1059 strncpy(argv[0], "init", strlen(argv[0])); 1060 /* Wipe argv[1]-argv[N] so they don't clutter the ps listing */ 1061 while (*++argv) 1062 memset(*argv, 0, strlen(*argv)); 1063 1064 /* Set up signal handlers */ 1065 if (!DEBUG_INIT) { 1066 struct sigaction sa; 1067 1068 bb_signals(0 1069 + (1 << SIGUSR1) /* halt */ 1070 + (1 << SIGTERM) /* reboot */ 1071 + (1 << SIGUSR2) /* poweroff */ 1072 , halt_reboot_pwoff); 1073 signal(SIGQUIT, restart_handler); /* re-exec another init */ 1074 1075 /* Stop handler must allow only SIGCONT inside itself */ 1076 memset(&sa, 0, sizeof(sa)); 1077 sigfillset(&sa.sa_mask); 1078 sigdelset(&sa.sa_mask, SIGCONT); 1079 sa.sa_handler = stop_handler; 1080 /* NB: sa_flags doesn't have SA_RESTART. 1081 * It must be able to interrupt wait(). 1082 */ 1083 sigaction_set(SIGTSTP, &sa); /* pause */ 1084 /* Does not work as intended, at least in 2.6.20. 1085 * SIGSTOP is simply ignored by init: 1086 */ 1087 sigaction_set(SIGSTOP, &sa); /* pause */ 1088 1089 /* SIGINT (Ctrl-Alt-Del) must interrupt wait(), 1090 * setting handler without SA_RESTART flag. 1091 */ 1092 bb_signals_recursive_norestart((1 << SIGINT), record_signo); 1093 } 1094 1095 /* Set up "reread /etc/inittab" handler. 1096 * Handler is set up without SA_RESTART, it will interrupt syscalls. 1097 */ 1098 if (!DEBUG_INIT && ENABLE_FEATURE_USE_INITTAB) 1099 bb_signals_recursive_norestart((1 << SIGHUP), record_signo); 988 1100 989 1101 /* Now run everything that needs to be run */ 990 991 1102 /* First run the sysinit command */ 992 1103 run_actions(SYSINIT); 993 1104 check_delayed_sigs(); 994 1105 /* Next run anything that wants to block */ 995 1106 run_actions(WAIT); 996 1107 check_delayed_sigs(); 997 1108 /* Next run anything to be run only once */ 998 1109 run_actions(ONCE); 999 1110 1000 #if ENABLE_FEATURE_USE_INITTAB 1001 /* Redefine SIGHUP to reread /etc/inittab */ 1002 signal(SIGHUP, reload_signal); 1003 #else 1004 signal(SIGHUP, SIG_IGN); 1005 #endif /* FEATURE_USE_INITTAB */ 1006 1007 /* Now run the looping stuff for the rest of forever */ 1111 /* Now run the looping stuff for the rest of forever. 1112 */ 1008 1113 while (1) { 1009 /* run the respawn stuff */ 1010 run_actions(RESPAWN); 1011 1012 /* run the askfirst stuff */ 1013 run_actions(ASKFIRST); 1014 1015 /* Don't consume all CPU time -- sleep a bit */ 1114 int maybe_WNOHANG; 1115 1116 maybe_WNOHANG = check_delayed_sigs(); 1117 1118 /* (Re)run the respawn/askfirst stuff */ 1119 run_actions(RESPAWN | ASKFIRST); 1120 maybe_WNOHANG |= check_delayed_sigs(); 1121 1122 /* Don't consume all CPU time - sleep a bit */ 1016 1123 sleep(1); 1017 1018 /* Wait for a child process to exit */ 1019 wpid = wait(NULL); 1020 while (wpid > 0) { 1021 /* Find out who died and clean up their corpse */ 1022 for (a = init_action_list; a; a = a->next) { 1023 if (a->pid == wpid) { 1024 /* Set the pid to 0 so that the process gets 1025 * restarted by run_actions() */ 1026 a->pid = 0; 1027 message(L_LOG, "process '%s' (pid %d) exited. " 1028 "Scheduling it for restart.", 1029 a->command, wpid); 1030 } 1124 maybe_WNOHANG |= check_delayed_sigs(); 1125 1126 /* Wait for any child process(es) to exit. 1127 * 1128 * If check_delayed_sigs above reported that a signal 1129 * was caught, wait will be nonblocking. This ensures 1130 * that if SIGHUP has reloaded inittab, respawn and askfirst 1131 * actions will not be delayed until next child death. 1132 */ 1133 if (maybe_WNOHANG) 1134 maybe_WNOHANG = WNOHANG; 1135 while (1) { 1136 pid_t wpid; 1137 struct init_action *a; 1138 1139 /* If signals happen _in_ the wait, they interrupt it, 1140 * bb_signals_recursive_norestart set them up that way 1141 */ 1142 wpid = waitpid(-1, NULL, maybe_WNOHANG); 1143 if (wpid <= 0) 1144 break; 1145 1146 a = mark_terminated(wpid); 1147 if (a) { 1148 message(L_LOG, "process '%s' (pid %d) exited. " 1149 "Scheduling for restart.", 1150 a->command, wpid); 1031 1151 } 1032 /* see if anyone else is waiting to be reaped */ 1033 wpid = waitpid(-1, NULL, WNOHANG); 1034 } 1035 } 1036 } 1152 /* See if anyone else is waiting to be reaped */ 1153 maybe_WNOHANG = WNOHANG; 1154 } 1155 } /* while (1) */ 1156 } 1157 1158 //usage:#define linuxrc_trivial_usage NOUSAGE_STR 1159 //usage:#define linuxrc_full_usage "" 1160 1161 //usage:#define init_trivial_usage 1162 //usage: "" 1163 //usage:#define init_full_usage "\n\n" 1164 //usage: "Init is the parent of all processes" 1165 //usage: 1166 //usage:#define init_notes_usage 1167 //usage: "This version of init is designed to be run only by the kernel.\n" 1168 //usage: "\n" 1169 //usage: "BusyBox init doesn't support multiple runlevels. The runlevels field of\n" 1170 //usage: "the /etc/inittab file is completely ignored by BusyBox init. If you want\n" 1171 //usage: "runlevels, use sysvinit.\n" 1172 //usage: "\n" 1173 //usage: "BusyBox init works just fine without an inittab. If no inittab is found,\n" 1174 //usage: "it has the following default behavior:\n" 1175 //usage: "\n" 1176 //usage: " ::sysinit:/etc/init.d/rcS\n" 1177 //usage: " ::askfirst:/bin/sh\n" 1178 //usage: " ::ctrlaltdel:/sbin/reboot\n" 1179 //usage: " ::shutdown:/sbin/swapoff -a\n" 1180 //usage: " ::shutdown:/bin/umount -a -r\n" 1181 //usage: " ::restart:/sbin/init\n" 1182 //usage: "\n" 1183 //usage: "if it detects that /dev/console is _not_ a serial console, it will also run:\n" 1184 //usage: "\n" 1185 //usage: " tty2::askfirst:/bin/sh\n" 1186 //usage: " tty3::askfirst:/bin/sh\n" 1187 //usage: " tty4::askfirst:/bin/sh\n" 1188 //usage: "\n" 1189 //usage: "If you choose to use an /etc/inittab file, the inittab entry format is as follows:\n" 1190 //usage: "\n" 1191 //usage: " <id>:<runlevels>:<action>:<process>\n" 1192 //usage: "\n" 1193 //usage: " <id>:\n" 1194 //usage: "\n" 1195 //usage: " WARNING: This field has a non-traditional meaning for BusyBox init!\n" 1196 //usage: " The id field is used by BusyBox init to specify the controlling tty for\n" 1197 //usage: " the specified process to run on. The contents of this field are\n" 1198 //usage: " appended to \"/dev/\" and used as-is. There is no need for this field to\n" 1199 //usage: " be unique, although if it isn't you may have strange results. If this\n" 1200 //usage: " field is left blank, the controlling tty is set to the console. Also\n" 1201 //usage: " note that if BusyBox detects that a serial console is in use, then only\n" 1202 //usage: " entries whose controlling tty is either the serial console or /dev/null\n" 1203 //usage: " will be run. BusyBox init does nothing with utmp. We don't need no\n" 1204 //usage: " stinkin' utmp.\n" 1205 //usage: "\n" 1206 //usage: " <runlevels>:\n" 1207 //usage: "\n" 1208 //usage: " The runlevels field is completely ignored.\n" 1209 //usage: "\n" 1210 //usage: " <action>:\n" 1211 //usage: "\n" 1212 //usage: " Valid actions include: sysinit, respawn, askfirst, wait,\n" 1213 //usage: " once, restart, ctrlaltdel, and shutdown.\n" 1214 //usage: "\n" 1215 //usage: " The available actions can be classified into two groups: actions\n" 1216 //usage: " that are run only once, and actions that are re-run when the specified\n" 1217 //usage: " process exits.\n" 1218 //usage: "\n" 1219 //usage: " Run only-once actions:\n" 1220 //usage: "\n" 1221 //usage: " 'sysinit' is the first item run on boot. init waits until all\n" 1222 //usage: " sysinit actions are completed before continuing. Following the\n" 1223 //usage: " completion of all sysinit actions, all 'wait' actions are run.\n" 1224 //usage: " 'wait' actions, like 'sysinit' actions, cause init to wait until\n" 1225 //usage: " the specified task completes. 'once' actions are asynchronous,\n" 1226 //usage: " therefore, init does not wait for them to complete. 'restart' is\n" 1227 //usage: " the action taken to restart the init process. By default this should\n" 1228 //usage: " simply run /sbin/init, but can be a script which runs pivot_root or it\n" 1229 //usage: " can do all sorts of other interesting things. The 'ctrlaltdel' init\n" 1230 //usage: " actions are run when the system detects that someone on the system\n" 1231 //usage: " console has pressed the CTRL-ALT-DEL key combination. Typically one\n" 1232 //usage: " wants to run 'reboot' at this point to cause the system to reboot.\n" 1233 //usage: " Finally the 'shutdown' action specifies the actions to taken when\n" 1234 //usage: " init is told to reboot. Unmounting filesystems and disabling swap\n" 1235 //usage: " is a very good here.\n" 1236 //usage: "\n" 1237 //usage: " Run repeatedly actions:\n" 1238 //usage: "\n" 1239 //usage: " 'respawn' actions are run after the 'once' actions. When a process\n" 1240 //usage: " started with a 'respawn' action exits, init automatically restarts\n" 1241 //usage: " it. Unlike sysvinit, BusyBox init does not stop processes from\n" 1242 //usage: " respawning out of control. The 'askfirst' actions acts just like\n" 1243 //usage: " respawn, except that before running the specified process it\n" 1244 //usage: " displays the line \"Please press Enter to activate this console.\"\n" 1245 //usage: " and then waits for the user to press enter before starting the\n" 1246 //usage: " specified process.\n" 1247 //usage: "\n" 1248 //usage: " Unrecognized actions (like initdefault) will cause init to emit an\n" 1249 //usage: " error message, and then go along with its business. All actions are\n" 1250 //usage: " run in the order they appear in /etc/inittab.\n" 1251 //usage: "\n" 1252 //usage: " <process>:\n" 1253 //usage: "\n" 1254 //usage: " Specifies the process to be executed and its command line.\n" 1255 //usage: "\n" 1256 //usage: "Example /etc/inittab file:\n" 1257 //usage: "\n" 1258 //usage: " # This is run first except when booting in single-user mode\n" 1259 //usage: " #\n" 1260 //usage: " ::sysinit:/etc/init.d/rcS\n" 1261 //usage: " \n" 1262 //usage: " # /bin/sh invocations on selected ttys\n" 1263 //usage: " #\n" 1264 //usage: " # Start an \"askfirst\" shell on the console (whatever that may be)\n" 1265 //usage: " ::askfirst:-/bin/sh\n" 1266 //usage: " # Start an \"askfirst\" shell on /dev/tty2-4\n" 1267 //usage: " tty2::askfirst:-/bin/sh\n" 1268 //usage: " tty3::askfirst:-/bin/sh\n" 1269 //usage: " tty4::askfirst:-/bin/sh\n" 1270 //usage: " \n" 1271 //usage: " # /sbin/getty invocations for selected ttys\n" 1272 //usage: " #\n" 1273 //usage: " tty4::respawn:/sbin/getty 38400 tty4\n" 1274 //usage: " tty5::respawn:/sbin/getty 38400 tty5\n" 1275 //usage: " \n" 1276 //usage: " \n" 1277 //usage: " # Example of how to put a getty on a serial line (for a terminal)\n" 1278 //usage: " #\n" 1279 //usage: " #::respawn:/sbin/getty -L ttyS0 9600 vt100\n" 1280 //usage: " #::respawn:/sbin/getty -L ttyS1 9600 vt100\n" 1281 //usage: " #\n" 1282 //usage: " # Example how to put a getty on a modem line\n" 1283 //usage: " #::respawn:/sbin/getty 57600 ttyS2\n" 1284 //usage: " \n" 1285 //usage: " # Stuff to do when restarting the init process\n" 1286 //usage: " ::restart:/sbin/init\n" 1287 //usage: " \n" 1288 //usage: " # Stuff to do before rebooting\n" 1289 //usage: " ::ctrlaltdel:/sbin/reboot\n" 1290 //usage: " ::shutdown:/bin/umount -a -r\n" 1291 //usage: " ::shutdown:/sbin/swapoff -a\n"
Note:
See TracChangeset
for help on using the changeset viewer.