busybox init进程分析和基本使用叁

init/init.c

int init_main(int argc UNUSED_PARAM, char **argv)
{
	struct sigaction sa;

	INIT_G();

	/* Some users send poweroff signals to init VERY early.
	 * To handle this, mask signals early.
	 */
	/* sigemptyset(&G.delayed_sigset); - done by INIT_G() */
	sigaddset(&G.delayed_sigset, SIGINT);  /* Ctrl-Alt-Del */
	sigaddset(&G.delayed_sigset, SIGQUIT); /* re-exec another init */
#ifdef SIGPWR
	sigaddset(&G.delayed_sigset, SIGPWR);  /* halt */
#endif
	sigaddset(&G.delayed_sigset, SIGUSR1); /* halt */
	sigaddset(&G.delayed_sigset, SIGTERM); /* reboot */
	sigaddset(&G.delayed_sigset, SIGUSR2); /* poweroff */
#if ENABLE_FEATURE_USE_INITTAB
	sigaddset(&G.delayed_sigset, SIGHUP);  /* reread /etc/inittab */
#endif
	sigaddset(&G.delayed_sigset, SIGCHLD); /* make sigtimedwait() exit on SIGCHLD */
	sigprocmask(SIG_BLOCK, &G.delayed_sigset, NULL);

#if DEBUG_SEGV_HANDLER
	memset(&sa, 0, sizeof(sa));
	sa.sa_sigaction = handle_sigsegv;
	sa.sa_flags = SA_SIGINFO;
	sigaction_set(SIGSEGV, &sa);
	sigaction_set(SIGILL, &sa);
	sigaction_set(SIGFPE, &sa);
	sigaction_set(SIGBUS, &sa);
#endif

	if (argv[1] && strcmp(argv[1], "-q") == 0) {
		return kill(1, SIGHUP);
	}

#if !DEBUG_INIT
	/* Expect to be invoked as init with PID=1 or be invoked as linuxrc */
	if (getpid() != 1
	 && (!ENABLE_LINUXRC || applet_name[0] != 'l') /* not linuxrc? */
	) {
		bb_simple_error_msg_and_die("must be run as PID 1");
	}

# ifdef RB_DISABLE_CAD
	/* Turn off rebooting via CTL-ALT-DEL - we get a
	 * SIGINT on CAD so we can shut things down gracefully... */
	reboot(RB_DISABLE_CAD); /* misnomer */
# endif
#endif

	/* If, say, xmalloc would ever die, we don't want to oops kernel
	 * by exiting.
	 * NB: we set die_func *after* PID 1 check and bb_show_usage.
	 * Otherwise, for example, "init u" ("please rexec yourself"
	 * command for sysvinit) will show help text (which isn't too bad),
	 * *and sleep forever* (which is bad!)
	 */
	die_func = sleep_much;

	/* Figure out where the default console should be */
	console_init();
	set_sane_term();
	xchdir("/");
	setsid();

	/* Make sure environs is set to something sane */
	putenv((char *) "HOME=/");
	putenv((char *) bb_PATH_root_path);
	putenv((char *) "SHELL=/bin/sh");
	putenv((char *) "USER=root"); /* needed? why? */

	if (argv[1])
		xsetenv("RUNLEVEL", argv[1]);

#if !ENABLE_FEATURE_INIT_QUIET
	/* Hello world */
	message(L_CONSOLE | L_LOG, "init started: %s", bb_banner);
#endif

	/* Check if we are supposed to be in single user mode */
	if (argv[1]
	 && (strcmp(argv[1], "single") == 0 || strcmp(argv[1], "-s") == 0 || LONE_CHAR(argv[1], '1'))
	) {
		/* ??? shouldn't we set RUNLEVEL="b" here? */
		/* Start a shell on console */
		new_init_action(RESPAWN, bb_default_login_shell, "");
	} else {
		/* Not in single user mode - see what inittab says */

		/* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined,
		 * then parse_inittab() simply adds in some default
		 * actions (i.e., INIT_SCRIPT and a pair
		 * of "askfirst" shells) */
		parse_inittab();  // 一上来 就解析和读取inittab文件
	}

#if ENABLE_SELINUX
	if (getenv("SELINUX_INIT") == NULL) {
		int enforce = 0;

		putenv((char*)"SELINUX_INIT=YES");
		if (selinux_init_load_policy(&enforce) == 0) {
			BB_EXECVP(argv[0], argv);
		} else if (enforce > 0) {
			/* SELinux in enforcing mode but load_policy failed */
			message(L_CONSOLE, "can't load SELinux Policy. "
				"Machine is in enforcing mode. Halting now.");
			return EXIT_FAILURE;
		}
	}
#endif

#if ENABLE_FEATURE_INIT_MODIFY_CMDLINE
	/* Make the command line just say "init"  - that's all, nothing else */
	strncpy(argv[0], "init", strlen(argv[0]));
	/* Wipe argv[1]-argv[N] so they don't clutter the ps listing */
	while (*++argv)
		nuke_str(*argv);
#endif

	/* Set up STOP signal handlers */
	/* Stop handler must allow only SIGCONT inside itself */
	memset(&sa, 0, sizeof(sa));
	sigfillset(&sa.sa_mask);
	sigdelset(&sa.sa_mask, SIGCONT);
	sa.sa_handler = stop_handler;
	sa.sa_flags = SA_RESTART;
	sigaction_set(SIGTSTP, &sa); /* pause */
	/* Does not work as intended, at least in 2.6.20.
	 * SIGSTOP is simply ignored by init
	 * (NB: behavior might differ under strace):
	 */
	sigaction_set(SIGSTOP, &sa); /* pause */

	/* Now run everything that needs to be run */
	/* First run the sysinit command */
	

	run_actions(SYSINIT);
	check_delayed_sigs(&G.zero_ts);
	/* Next run anything that wants to block */
	run_actions(WAIT);
	check_delayed_sigs(&G.zero_ts);
	/* Next run anything to be run only once */
	run_actions(ONCE);
	
	
	

	/* Now run the looping stuff for the rest of forever */
	while (1) {
		/* (Re)run the respawn/askfirst stuff */
		run_actions(RESPAWN | ASKFIRST);

		/* Wait for any signal (typically it's SIGCHLD) */
		check_delayed_sigs(NULL); /* NULL timespec makes it wait */

		/* Wait for any child process(es) to exit */
		while (1) {
			pid_t wpid;
			struct init_action *a;

			wpid = waitpid(-1, NULL, WNOHANG);
			if (wpid <= 0)
				break;

			a = mark_terminated(wpid);
			if (a) {
				message(L_LOG, "process '%s' (pid %u) exited. "
						"Scheduling for restart.",
						a->command, (unsigned)wpid);
			}
		}
		
		
		/* Don't consume all CPU time - sleep a bit */
		sleep1();
	} /* while (1) */
}
(1)读取和解析/etc/inittab,根据inittab里面的设置,启动不同的进程
(2)运行inittab系统初始化rcs脚本    
	::sysinit:/etc/init.d/rcS
	mount -a 根据/etc/fstab 挂载相应的系统
	可配置ip地址
	ifconfig eth0 xxxx   netmask 255.255.255.0 
	route add default gw  xxx
	route add  xx  dev eth0
	mount -o nolock xxx:xxx  /mnt
	mount -o nolock xxxx:xxxx  /mnt
(3)运行inittab WAIT相关的脚本
(4)运行inittab ONCE相关的脚本
(5)运行inittab RESPAWN | ASKFIRST 相关的脚本  是否免密登录
       ::askfirst:-/bin/sh    按回车就直接进入shell 
	   ::respawn:/sbin/getty -L ttyS000 115200 vt100 -n root -I "Auto login as root ..."
	   ::respawn:-/bin/login   
	   之后运行/etc/profile 
	   

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

今天少内耗10点半睡觉和今天早晚运动

老铁的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值