/* Standard reboot/shutdown utilities talk to init using /dev/initctl. * We should check if the fifo was recreated and reopen it. */ static void parse(void *UNUSED(arg), int fd, int UNUSED(events)) { struct init_request rq; _d("Receiving request on %s...", FINIT_FIFO); while (1) { ssize_t len = read(fd, &rq, sizeof(rq)); if (len <= 0) { if (-1 == len) { if (EINTR == errno) continue; if (EAGAIN == errno) break; _e("Failed reading initctl request, error %d: %s", errno, strerror(errno)); } break; } if (rq.magic != INIT_MAGIC || len != sizeof(rq)) { _e("Invalid initctl request."); break; } _d("Magic OK..."); if (rq.cmd == INIT_CMD_RUNLVL) { switch (rq.runlevel) { case '0': _d("Halting system (SIGUSR2)"); do_shutdown(SIGUSR2); break; case 's': case 'S': rq.runlevel = '1'; /* Fall through to regular processing */ case '1'...'5': _d("Setting new runlevel %c ...", rq.runlevel); svc_runlevel(rq.runlevel - '0'); break; case '6': _d("Rebooting system (SIGUSR1)"); do_shutdown(SIGUSR1); break; default: _d("Unsupported runlevel: %d", rq.runlevel); break; } } else if (rq.cmd == INIT_CMD_DEBUG) { debug = !debug; } else { _d("Unsupported cmd: %d", rq.cmd); } }
int main(int argc, char* argv[]) { if (getpid() != 1) return client(argc, argv); /* * Hello world. */ banner(); /* * Initial setup of signals, ignore all until we're up. */ sig_init(); /* * Mount base file system, kernel is assumed to run devtmpfs for /dev */ chdir("/"); umask(0); mount("none", "/proc", "proc", 0, NULL); mount("none", "/proc/bus/usb", "usbfs", 0, NULL); mount("none", "/sys", "sysfs", 0, NULL); mkdir("/dev/pts", 0755); mkdir("/dev/shm", 0755); mount("none", "/dev/pts", "devpts", 0, "gid=5,mode=620"); mount("none", "/dev/shm", "tmpfs", 0, NULL); umask(022); /* * Parse kernel parameters */ parse_kernel_cmdline(); /* * Populate /dev and prepare for runtime events from kernel. */ run_interactive(SETUP_DEVFS, "Populating device tree"); /* * Parse configuration file */ parse_finit_conf(FINIT_CONF); /* * Load plugins. Must run after finit.conf has registered * all services, or service plugins won't have anything to * hook on to. */ print_desc("Loading plugins", NULL); print_result(plugin_load_all(PLUGIN_PATH)); /* * Mount filesystems */ #ifdef REMOUNT_ROOTFS_RW run("/bin/mount -n -o remount,rw /"); #endif #ifdef SYSROOT run(SYSROOT, "/", NULL, MS_MOVE, NULL); #endif _d("Root FS up, calling hooks ..."); plugin_run_hooks(HOOK_ROOTFS_UP); umask(0); run("/bin/mount -na"); run("/sbin/swapon -ea"); umask(0022); /* Cleanup stale files, if any still linger on. */ run_interactive("rm -rf /tmp/* /var/run/* /var/lock/*", "Cleanup temporary directories"); /* Base FS up, enable standard SysV init signals */ sig_setup(); _d("Base FS up, calling hooks ..."); plugin_run_hooks(HOOK_BASEFS_UP); /* * Start all bootstrap tasks, no network available! */ svc_bootstrap(); /* * Network stuff */ /* Setup kernel specific settings, e.g. allow broadcast ping, etc. */ run("/sbin/sysctl -e -p /etc/sysctl.conf >/dev/null"); /* Set initial hostname. */ set_hostname(hostname); ifconfig("lo", "127.0.0.1", "255.0.0.0", 1); if (network) run_interactive(network, "Starting networking: %s", network); umask(022); /* Hooks that rely on loopback, or basic networking being up. */ plugin_run_hooks(HOOK_NETWORK_UP); /* * Start all tasks/services in the configured runlevel */ svc_runlevel(cfglevel); _d("Running svc up hooks ..."); plugin_run_hooks(HOOK_SVC_UP); /* * Run startup scripts in /etc/finit.d/, if any. */ if (rcsd && fisdir(rcsd)) { _d("Running startup scripts in %s ...", rcsd); run_parts(rcsd, NULL); } /* Hooks that should run at the very end */ plugin_run_hooks(HOOK_SYSTEM_UP); /* * Enter main loop to monior /dev/initctl and services */ return run_loop(); }