예제 #1
0
파일: initctl.c 프로젝트: cmatsuoka/finit
/* 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);
		}
	}
예제 #2
0
파일: finit.c 프로젝트: KroMignon/finit
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();
}