Changeset 3621 in MondoRescue for branches/3.3/mindi-busybox/init/init.c


Ignore:
Timestamp:
Dec 20, 2016, 4:07:32 PM (7 years ago)
Author:
Bruno Cornec
Message:

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

Location:
branches/3.3
Files:
1 edited
1 copied

Legend:

Unmodified
Added
Removed
  • branches/3.3/mindi-busybox/init/init.c

    r3232 r3621  
    1010 */
    1111
    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 
    1712//config:config INIT
    1813//config:   bool "init"
     
    2217//config:     init is the first program run when the system boots.
    2318//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:
    2430//config:config FEATURE_USE_INITTAB
    2531//config:   bool "Support reading an inittab file"
    2632//config:   default y
    27 //config:   depends on INIT
     33//config:   depends on INIT || LINUXRC
    2834//config:   help
    2935//config:     Allow init to read an inittab file when the system boot.
     
    5258//config:   bool "Run commands with leading dash with controlling tty"
    5359//config:   default y
    54 //config:   depends on INIT
     60//config:   depends on INIT || LINUXRC
    5561//config:   help
    5662//config:     If this option is enabled, init will try to give a controlling
     
    6773//config:   bool "Enable init to write to syslog"
    6874//config:   default y
    69 //config:   depends on INIT
     75//config:   depends on INIT || LINUXRC
    7076//config:
    7177//config:config FEATURE_EXTRA_QUIET
    7278//config:   bool "Be _extra_ quiet on boot"
    7379//config:   default y
    74 //config:   depends on INIT
     80//config:   depends on INIT || LINUXRC
    7581//config:   help
    7682//config:     Prevent init from logging some messages to the console during boot.
     
    7985//config:   bool "Support dumping core for child processes (debugging only)"
    8086//config:   default y
    81 //config:   depends on INIT
     87//config:   depends on INIT || LINUXRC
    8288//config:   help
    8389//config:     If this option is enabled and the file /.init_enable_core
     
    8692//config:     will not generate any core files.
    8793//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:
    9994//config:config INIT_TERMINAL_TYPE
    10095//config:   string "Initial terminal type"
    10196//config:   default "linux"
    102 //config:   depends on INIT
     97//config:   depends on INIT || LINUXRC
    10398//config:   help
    10499//config:     This is the initial value set by init for the TERM environment
     
    108103//config:     Note that on Linux, init attempts to detect serial terminal and
    109104//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
    110126
    111127#define DEBUG_SEGV_HANDLER 0
     
    113129#include "libbb.h"
    114130#include <syslog.h>
    115 #include <paths.h>
    116131#include <sys/resource.h>
    117132#ifdef __linux__
     
    141156#define DEBUG_INIT 0
    142157
    143 #define COMMAND_SIZE      256
    144158#define CONSOLE_NAME_SIZE 32
    145159
    146160/* Default sysinit script. */
    147161#ifndef INIT_SCRIPT
    148 #define INIT_SCRIPT  "/etc/init.d/rcS"
     162# define INIT_SCRIPT  "/etc/init.d/rcS"
    149163#endif
    150164
     
    196210    uint8_t action_type;
    197211    char terminal[CONSOLE_NAME_SIZE];
    198     char command[COMMAND_SIZE];
     212    char command[1];
    199213};
    200214
     
    224238    va_start(arguments, fmt);
    225239    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;
    228242    va_end(arguments);
    229243
     
    399413
    400414/* Wrapper around exec:
    401  * Takes string (max COMMAND_SIZE chars).
     415 * Takes string.
    402416 * If chars like '>' detected, execs '[-]/bin/sh -c "exec ......."'.
    403417 * Otherwise splits words on whitespace, deals with leading dash,
     
    407421static void init_exec(const char *command)
    408422{
    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] == '/' */);
    413432    command += dash;
    414433
     
    535554
    536555    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);
    542557        for (a = init_action_list; a; a = a->next) {
    543558            if (a->pid == pid) {
     
    627642    }
    628643
    629     a = xzalloc(sizeof(*a));
     644    a = xzalloc(sizeof(*a) + strlen(command));
    630645
    631646    /* Append to the end of the list */
     
    633648    *nextp = a;
    634649    a->action_type = action_type;
    635     safe_strncpy(a->command, command, sizeof(a->command));
     650    strcpy(a->command, command);
    636651    safe_strncpy(a->terminal, cons, sizeof(a->terminal));
    637     dbg_message(L_LOG | L_CONSOLE, "command='%s' action=%d tty='%s'\n",
     652    dbg_message(L_LOG | L_CONSOLE, "command='%s' action=%x tty='%s'\n",
    638653        a->command, a->action_type, a->terminal);
    639654}
     
    641656/* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined,
    642657 * then parse_inittab() simply adds in some default
    643  * actions(i.e., runs INIT_SCRIPT and then starts a pair
     658 * actions (i.e., runs INIT_SCRIPT and then starts a pair
    644659 * of "askfirst" shells).  If CONFIG_FEATURE_USE_INITTAB
    645660 * _is_ defined, but /etc/inittab is missing, this
     
    656671    {
    657672        /* 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, "");
    667675        /* Askfirst shell on tty1-4 */
    668676        new_init_action(ASKFIRST, bb_default_login_shell, "");
     
    671679        new_init_action(ASKFIRST, bb_default_login_shell, VC_3);
    672680        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", "");
    675689        return;
    676690    }
     
    787801 */
    788802
    789 /* The SIGUSR[12]/SIGTERM handler */
     803/* The SIGPWR/SIGUSR[12]/SIGTERM handler */
    790804static void halt_reboot_pwoff(int sig) NORETURN;
    791805static void halt_reboot_pwoff(int sig)
     
    820834/* Handler for QUIT - exec "restart" action,
    821835 * else (no such action defined) do nothing */
    822 static void restart_handler(int sig UNUSED_PARAM)
     836static void exec_restart_action(void)
    823837{
    824838    struct init_action *a;
     
    932946    /* Remove stale entries and SYSINIT entries.
    933947     * We never rerun SYSINIT entries anyway,
    934      * removing them too saves a few bytes */
     948     * removing them too saves a few bytes
     949     */
    935950    nextp = &init_action_list;
    936951    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) {
    938959            *nextp = a->next;
    939960            free(a);
     
    966987        if (sig == SIGINT)
    967988            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        }
    9681003    }
    9691004}
     
    9961031#endif
    9971032
     1033static void sleep_much(void)
     1034{
     1035        sleep(30 * 24*60*60);
     1036}
     1037
    9981038int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
    9991039int init_main(int argc UNUSED_PARAM, char **argv)
     
    10191059        /* Expect to be invoked as init with PID=1 or be invoked as linuxrc */
    10201060        if (getpid() != 1
    1021          && (!ENABLE_FEATURE_INITRD || applet_name[0] != 'l') /* not linuxrc? */
     1061         && (!ENABLE_LINUXRC || applet_name[0] != 'l') /* not linuxrc? */
    10221062        ) {
    10231063            bb_error_msg_and_die("must be run as PID 1");
     
    10321072    /* If, say, xmalloc would ever die, we don't want to oops kernel
    10331073     * 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.
    10351075     * Otherwise, for example, "init u" ("please rexec yourself"
    10361076     * command for sysvinit) will show help text (which isn't too bad),
    10371077     * *and sleep forever* (which is bad!)
    10381078     */
    1039     die_sleep = 30 * 24*60*60;
     1079    die_func = sleep_much;
    10401080
    10411081    /* Figure out where the default console should be */
     
    10591099#endif
    10601100
     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! */
    10611104/* struct sysinfo is linux-specific */
    1062 #ifdef __linux__
     1105# ifdef __linux__
    10631106    /* 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*/ {
    10651108        struct sysinfo info;
    10661109
     
    10761119        }
    10771120    }
     1121# endif
    10781122#endif
    10791123
     
    10901134        /* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined,
    10911135         * then parse_inittab() simply adds in some default
    1092          * actions(i.e., INIT_SCRIPT and a pair
    1093          * of "askfirst" shells */
     1136         * actions (i.e., INIT_SCRIPT and a pair
     1137         * of "askfirst" shells) */
    10941138        parse_inittab();
    10951139    }
     
    11111155#endif
    11121156
    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    }
    11181164
    11191165    /* Set up signal handlers */
    11201166    if (!DEBUG_INIT) {
    11211167        struct sigaction sa;
    1122 
    1123         bb_signals(0
    1124             + (1 << SIGUSR1) /* halt */
    1125             + (1 << SIGTERM) /* reboot */
    1126             + (1 << SIGUSR2) /* poweroff */
    1127             , halt_reboot_pwoff);
    1128         signal(SIGQUIT, restart_handler); /* re-exec another init */
    11291168
    11301169        /* Stop handler must allow only SIGCONT inside itself */
     
    11421181        sigaction_set(SIGSTOP, &sa); /* pause */
    11431182
    1144         /* SIGINT (Ctrl-Alt-Del) must interrupt wait(),
     1183        /* These signals must interrupt wait(),
    11451184         * setting handler without SA_RESTART flag.
    11461185         */
    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    }
    11551200
    11561201    /* Now run everything that needs to be run */
     
    12171262//usage:       ""
    12181263//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:    )
    12201272//usage:
    12211273//usage:#define init_notes_usage
     
    12351287//usage:    "   ::shutdown:/bin/umount -a -r\n"
    12361288//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"
    12401289//usage:    "   tty2::askfirst:/bin/sh\n"
    12411290//usage:    "   tty3::askfirst:/bin/sh\n"
     
    12531302//usage:    "       appended to \"/dev/\" and used as-is. There is no need for this field to\n"
    12541303//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"
    12601305//usage:    "\n"
    12611306//usage:    "   <runlevels>:\n"
Note: See TracChangeset for help on using the changeset viewer.