Changeset 3621 in MondoRescue for branches/3.3/mindi-busybox/init/init.c
- Timestamp:
- Dec 20, 2016, 4:07:32 PM (7 years ago)
- Location:
- branches/3.3
- Files:
-
- 1 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/3.3/mindi-busybox/init/init.c
r3232 r3621 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.o16 17 12 //config:config INIT 18 13 //config: bool "init" … … 22 17 //config: init is the first program run when the system boots. 23 18 //config: 19 //config:config LINUXRC 20 //config: bool "Support running init from within an initrd (not initramfs)" 21 //config: default y 22 //config: select FEATURE_SYSLOG 23 //config: help 24 //config: Legacy support for running init under the old-style initrd. Allows 25 //config: the name linuxrc to act as init, and it doesn't assume init is PID 1. 26 //config: 27 //config: This does not apply to initramfs, which runs /init as PID 1 and 28 //config: requires no special support. 29 //config: 24 30 //config:config FEATURE_USE_INITTAB 25 31 //config: bool "Support reading an inittab file" 26 32 //config: default y 27 //config: depends on INIT 33 //config: depends on INIT || LINUXRC 28 34 //config: help 29 35 //config: Allow init to read an inittab file when the system boot. … … 52 58 //config: bool "Run commands with leading dash with controlling tty" 53 59 //config: default y 54 //config: depends on INIT 60 //config: depends on INIT || LINUXRC 55 61 //config: help 56 62 //config: If this option is enabled, init will try to give a controlling … … 67 73 //config: bool "Enable init to write to syslog" 68 74 //config: default y 69 //config: depends on INIT 75 //config: depends on INIT || LINUXRC 70 76 //config: 71 77 //config:config FEATURE_EXTRA_QUIET 72 78 //config: bool "Be _extra_ quiet on boot" 73 79 //config: default y 74 //config: depends on INIT 80 //config: depends on INIT || LINUXRC 75 81 //config: help 76 82 //config: Prevent init from logging some messages to the console during boot. … … 79 85 //config: bool "Support dumping core for child processes (debugging only)" 80 86 //config: default y 81 //config: depends on INIT 87 //config: depends on INIT || LINUXRC 82 88 //config: help 83 89 //config: If this option is enabled and the file /.init_enable_core … … 86 92 //config: will not generate any core files. 87 93 //config: 88 //config:config FEATURE_INITRD89 //config: bool "Support running init from within an initrd (not initramfs)"90 //config: default y91 //config: depends on INIT92 //config: help93 //config: Legacy support for running init under the old-style initrd. Allows94 //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 and97 //config: requires no special support.98 //config:99 94 //config:config INIT_TERMINAL_TYPE 100 95 //config: string "Initial terminal type" 101 96 //config: default "linux" 102 //config: depends on INIT 97 //config: depends on INIT || LINUXRC 103 98 //config: help 104 99 //config: This is the initial value set by init for the TERM environment … … 108 103 //config: Note that on Linux, init attempts to detect serial terminal and 109 104 //config: sets TERM to "vt102" if one is found. 105 //config: 106 //config:config FEATURE_INIT_MODIFY_CMDLINE 107 //config: bool "Modify the command-line to \"init\"" 108 //config: default y 109 //config: depends on INIT || LINUXRC 110 //config: help 111 //config: When launched as PID 1 and after parsing its arguments, init 112 //config: wipes all the arguments but argv[0] and rewrites argv[0] to 113 //config: contain only "init", so that its command-line appears solely as 114 //config: "init" in tools such as ps. 115 //config: If this option is set to Y, init will keep its original behavior, 116 //config: otherwise, all the arguments including argv[0] will be preserved, 117 //config: be they parsed or ignored by init. 118 //config: The original command-line used to launch init can then be 119 //config: retrieved in /proc/1/cmdline on Linux, for example. 120 121 //applet:IF_INIT(APPLET(init, BB_DIR_SBIN, BB_SUID_DROP)) 122 //applet:IF_LINUXRC(APPLET_ODDNAME(linuxrc, init, BB_DIR_ROOT, BB_SUID_DROP, linuxrc)) 123 124 //kbuild:lib-$(CONFIG_INIT) += init.o 125 //kbuild:lib-$(CONFIG_LINUXRC) += init.o 110 126 111 127 #define DEBUG_SEGV_HANDLER 0 … … 113 129 #include "libbb.h" 114 130 #include <syslog.h> 115 #include <paths.h>116 131 #include <sys/resource.h> 117 132 #ifdef __linux__ … … 141 156 #define DEBUG_INIT 0 142 157 143 #define COMMAND_SIZE 256144 158 #define CONSOLE_NAME_SIZE 32 145 159 146 160 /* Default sysinit script. */ 147 161 #ifndef INIT_SCRIPT 148 # define INIT_SCRIPT "/etc/init.d/rcS"162 # define INIT_SCRIPT "/etc/init.d/rcS" 149 163 #endif 150 164 … … 196 210 uint8_t action_type; 197 211 char terminal[CONSOLE_NAME_SIZE]; 198 char command[ COMMAND_SIZE];212 char command[1]; 199 213 }; 200 214 … … 224 238 va_start(arguments, fmt); 225 239 l = 1 + vsnprintf(msg + 1, sizeof(msg) - 2, fmt, arguments); 226 if (l > sizeof(msg) - 1)227 l = sizeof(msg) - 1;240 if (l > sizeof(msg) - 2) 241 l = sizeof(msg) - 2; 228 242 va_end(arguments); 229 243 … … 399 413 400 414 /* Wrapper around exec: 401 * Takes string (max COMMAND_SIZE chars).415 * Takes string. 402 416 * If chars like '>' detected, execs '[-]/bin/sh -c "exec ......."'. 403 417 * Otherwise splits words on whitespace, deals with leading dash, … … 407 421 static void init_exec(const char *command) 408 422 { 409 char *cmd[COMMAND_SIZE / 2]; 410 char buf[COMMAND_SIZE + 6]; /* COMMAND_SIZE+strlen("exec ")+1 */ 411 int dash = (command[0] == '-' /* maybe? && command[1] == '/' */); 412 423 /* +8 allows to write VLA sizes below more efficiently: */ 424 unsigned command_size = strlen(command) + 8; 425 /* strlen(command) + strlen("exec ")+1: */ 426 char buf[command_size]; 427 /* strlen(command) / 2 + 4: */ 428 char *cmd[command_size / 2]; 429 int dash; 430 431 dash = (command[0] == '-' /* maybe? && command[1] == '/' */); 413 432 command += dash; 414 433 … … 535 554 536 555 if (pid > 0) { 537 update_utmp(pid, DEAD_PROCESS, 538 /*tty_name:*/ NULL, 539 /*username:*/ NULL, 540 /*hostname:*/ NULL 541 ); 556 update_utmp_DEAD_PROCESS(pid); 542 557 for (a = init_action_list; a; a = a->next) { 543 558 if (a->pid == pid) { … … 627 642 } 628 643 629 a = xzalloc(sizeof(*a) );644 a = xzalloc(sizeof(*a) + strlen(command)); 630 645 631 646 /* Append to the end of the list */ … … 633 648 *nextp = a; 634 649 a->action_type = action_type; 635 s afe_strncpy(a->command, command, sizeof(a->command));650 strcpy(a->command, command); 636 651 safe_strncpy(a->terminal, cons, sizeof(a->terminal)); 637 dbg_message(L_LOG | L_CONSOLE, "command='%s' action=% dtty='%s'\n",652 dbg_message(L_LOG | L_CONSOLE, "command='%s' action=%x tty='%s'\n", 638 653 a->command, a->action_type, a->terminal); 639 654 } … … 641 656 /* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined, 642 657 * then parse_inittab() simply adds in some default 643 * actions (i.e., runs INIT_SCRIPT and then starts a pair658 * actions (i.e., runs INIT_SCRIPT and then starts a pair 644 659 * of "askfirst" shells). If CONFIG_FEATURE_USE_INITTAB 645 660 * _is_ defined, but /etc/inittab is missing, this … … 656 671 { 657 672 /* No inittab file - set up some default behavior */ 658 /* Reboot on Ctrl-Alt-Del */ 659 new_init_action(CTRLALTDEL, "reboot", ""); 660 /* Umount all filesystems on halt/reboot */ 661 new_init_action(SHUTDOWN, "umount -a -r", ""); 662 /* Swapoff on halt/reboot */ 663 if (ENABLE_SWAPONOFF) 664 new_init_action(SHUTDOWN, "swapoff -a", ""); 665 /* Prepare to restart init when a QUIT is received */ 666 new_init_action(RESTART, "init", ""); 673 /* Sysinit */ 674 new_init_action(SYSINIT, INIT_SCRIPT, ""); 667 675 /* Askfirst shell on tty1-4 */ 668 676 new_init_action(ASKFIRST, bb_default_login_shell, ""); … … 671 679 new_init_action(ASKFIRST, bb_default_login_shell, VC_3); 672 680 new_init_action(ASKFIRST, bb_default_login_shell, VC_4); 673 /* sysinit */ 674 new_init_action(SYSINIT, INIT_SCRIPT, ""); 681 /* Reboot on Ctrl-Alt-Del */ 682 new_init_action(CTRLALTDEL, "reboot", ""); 683 /* Umount all filesystems on halt/reboot */ 684 new_init_action(SHUTDOWN, "umount -a -r", ""); 685 /* Swapoff on halt/reboot */ 686 new_init_action(SHUTDOWN, "swapoff -a", ""); 687 /* Restart init when a QUIT is received */ 688 new_init_action(RESTART, "init", ""); 675 689 return; 676 690 } … … 787 801 */ 788 802 789 /* The SIG USR[12]/SIGTERM handler */803 /* The SIGPWR/SIGUSR[12]/SIGTERM handler */ 790 804 static void halt_reboot_pwoff(int sig) NORETURN; 791 805 static void halt_reboot_pwoff(int sig) … … 820 834 /* Handler for QUIT - exec "restart" action, 821 835 * else (no such action defined) do nothing */ 822 static void restart_handler(int sig UNUSED_PARAM)836 static void exec_restart_action(void) 823 837 { 824 838 struct init_action *a; … … 932 946 /* Remove stale entries and SYSINIT entries. 933 947 * We never rerun SYSINIT entries anyway, 934 * removing them too saves a few bytes */ 948 * removing them too saves a few bytes 949 */ 935 950 nextp = &init_action_list; 936 951 while ((a = *nextp) != NULL) { 937 if ((a->action_type & ~SYSINIT) == 0) { 952 /* 953 * Why pid == 0 check? 954 * Process can be removed from inittab and added *later*. 955 * If we delete its entry but process still runs, 956 * duplicate is spawned when the entry is re-added. 957 */ 958 if ((a->action_type & ~SYSINIT) == 0 && a->pid == 0) { 938 959 *nextp = a->next; 939 960 free(a); … … 966 987 if (sig == SIGINT) 967 988 run_actions(CTRLALTDEL); 989 if (sig == SIGQUIT) { 990 exec_restart_action(); 991 /* returns only if no restart action defined */ 992 } 993 if ((1 << sig) & (0 994 #ifdef SIGPWR 995 + (1 << SIGPWR) 996 #endif 997 + (1 << SIGUSR1) 998 + (1 << SIGUSR2) 999 + (1 << SIGTERM) 1000 )) { 1001 halt_reboot_pwoff(sig); 1002 } 968 1003 } 969 1004 } … … 996 1031 #endif 997 1032 1033 static void sleep_much(void) 1034 { 1035 sleep(30 * 24*60*60); 1036 } 1037 998 1038 int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 999 1039 int init_main(int argc UNUSED_PARAM, char **argv) … … 1019 1059 /* Expect to be invoked as init with PID=1 or be invoked as linuxrc */ 1020 1060 if (getpid() != 1 1021 && (!ENABLE_ FEATURE_INITRD|| applet_name[0] != 'l') /* not linuxrc? */1061 && (!ENABLE_LINUXRC || applet_name[0] != 'l') /* not linuxrc? */ 1022 1062 ) { 1023 1063 bb_error_msg_and_die("must be run as PID 1"); … … 1032 1072 /* If, say, xmalloc would ever die, we don't want to oops kernel 1033 1073 * by exiting. 1034 * NB: we set die_ sleep*after* PID 1 check and bb_show_usage.1074 * NB: we set die_func *after* PID 1 check and bb_show_usage. 1035 1075 * Otherwise, for example, "init u" ("please rexec yourself" 1036 1076 * command for sysvinit) will show help text (which isn't too bad), 1037 1077 * *and sleep forever* (which is bad!) 1038 1078 */ 1039 die_ sleep = 30 * 24*60*60;1079 die_func = sleep_much; 1040 1080 1041 1081 /* Figure out where the default console should be */ … … 1059 1099 #endif 1060 1100 1101 #if 0 1102 /* It's 2013, does anyone really still depend on this? */ 1103 /* If you do, consider adding swapon to sysinit actions then! */ 1061 1104 /* struct sysinfo is linux-specific */ 1062 # ifdef __linux__1105 # ifdef __linux__ 1063 1106 /* Make sure there is enough memory to do something useful. */ 1064 if (ENABLE_SWAPONOFF){1107 /*if (ENABLE_SWAPONOFF) - WRONG: we may have non-bbox swapon*/ { 1065 1108 struct sysinfo info; 1066 1109 … … 1076 1119 } 1077 1120 } 1121 # endif 1078 1122 #endif 1079 1123 … … 1090 1134 /* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined, 1091 1135 * then parse_inittab() simply adds in some default 1092 * actions (i.e., INIT_SCRIPT and a pair1093 * of "askfirst" shells */1136 * actions (i.e., INIT_SCRIPT and a pair 1137 * of "askfirst" shells) */ 1094 1138 parse_inittab(); 1095 1139 } … … 1111 1155 #endif 1112 1156 1113 /* Make the command line just say "init" - thats all, nothing else */ 1114 strncpy(argv[0], "init", strlen(argv[0])); 1115 /* Wipe argv[1]-argv[N] so they don't clutter the ps listing */ 1116 while (*++argv) 1117 memset(*argv, 0, strlen(*argv)); 1157 if (ENABLE_FEATURE_INIT_MODIFY_CMDLINE) { 1158 /* Make the command line just say "init" - that's all, nothing else */ 1159 strncpy(argv[0], "init", strlen(argv[0])); 1160 /* Wipe argv[1]-argv[N] so they don't clutter the ps listing */ 1161 while (*++argv) 1162 nuke_str(*argv); 1163 } 1118 1164 1119 1165 /* Set up signal handlers */ 1120 1166 if (!DEBUG_INIT) { 1121 1167 struct sigaction sa; 1122 1123 bb_signals(01124 + (1 << SIGUSR1) /* halt */1125 + (1 << SIGTERM) /* reboot */1126 + (1 << SIGUSR2) /* poweroff */1127 , halt_reboot_pwoff);1128 signal(SIGQUIT, restart_handler); /* re-exec another init */1129 1168 1130 1169 /* Stop handler must allow only SIGCONT inside itself */ … … 1142 1181 sigaction_set(SIGSTOP, &sa); /* pause */ 1143 1182 1144 /* SIGINT (Ctrl-Alt-Del)must interrupt wait(),1183 /* These signals must interrupt wait(), 1145 1184 * setting handler without SA_RESTART flag. 1146 1185 */ 1147 bb_signals_recursive_norestart((1 << SIGINT), record_signo); 1148 } 1149 1150 /* Set up "reread /etc/inittab" handler. 1151 * Handler is set up without SA_RESTART, it will interrupt syscalls. 1152 */ 1153 if (!DEBUG_INIT && ENABLE_FEATURE_USE_INITTAB) 1154 bb_signals_recursive_norestart((1 << SIGHUP), record_signo); 1186 bb_signals_recursive_norestart(0 1187 + (1 << SIGINT) /* Ctrl-Alt-Del */ 1188 + (1 << SIGQUIT) /* re-exec another init */ 1189 #ifdef SIGPWR 1190 + (1 << SIGPWR) /* halt */ 1191 #endif 1192 + (1 << SIGUSR1) /* halt */ 1193 + (1 << SIGTERM) /* reboot */ 1194 + (1 << SIGUSR2) /* poweroff */ 1195 #if ENABLE_FEATURE_USE_INITTAB 1196 + (1 << SIGHUP) /* reread /etc/inittab */ 1197 #endif 1198 , record_signo); 1199 } 1155 1200 1156 1201 /* Now run everything that needs to be run */ … … 1217 1262 //usage: "" 1218 1263 //usage:#define init_full_usage "\n\n" 1219 //usage: "Init is the parent of all processes" 1264 //usage: "Init is the first process started during boot. It never exits." 1265 //usage: IF_FEATURE_USE_INITTAB( 1266 //usage: "\n""It (re)spawns children according to /etc/inittab." 1267 //usage: ) 1268 //usage: IF_NOT_FEATURE_USE_INITTAB( 1269 //usage: "\n""This version of init doesn't use /etc/inittab," 1270 //usage: "\n""has fixed set of processed to run." 1271 //usage: ) 1220 1272 //usage: 1221 1273 //usage:#define init_notes_usage … … 1235 1287 //usage: " ::shutdown:/bin/umount -a -r\n" 1236 1288 //usage: " ::restart:/sbin/init\n" 1237 //usage: "\n"1238 //usage: "if it detects that /dev/console is _not_ a serial console, it will also run:\n"1239 //usage: "\n"1240 1289 //usage: " tty2::askfirst:/bin/sh\n" 1241 1290 //usage: " tty3::askfirst:/bin/sh\n" … … 1253 1302 //usage: " appended to \"/dev/\" and used as-is. There is no need for this field to\n" 1254 1303 //usage: " be unique, although if it isn't you may have strange results. If this\n" 1255 //usage: " field is left blank, the controlling tty is set to the console. Also\n" 1256 //usage: " note that if BusyBox detects that a serial console is in use, then only\n" 1257 //usage: " entries whose controlling tty is either the serial console or /dev/null\n" 1258 //usage: " will be run. BusyBox init does nothing with utmp. We don't need no\n" 1259 //usage: " stinkin' utmp.\n" 1304 //usage: " field is left blank, then the init's stdin/out will be used.\n" 1260 1305 //usage: "\n" 1261 1306 //usage: " <runlevels>:\n"
Note:
See TracChangeset
for help on using the changeset viewer.