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