BusyBox init及其inittab文件分析
时间:2010-10-13 来源:swinner1985
/* Line is: "id:runlevel_ignored:action:command" */ 这是BusyBox-1.11.1中init.c文件中的一句注释,该注释指明了inittab文件中每行的格式。以下对各字段进行简要解析: 1、id 尽管该格式与发行版linux的Sys V init类似,但是,id在BusyBox的init中具有不同的意义。对BusyBox而言,id用来指定启动进程的控制终端。如果所启动的进程并不是可以交互的shell,例如BusyBox的sh(ash),应该会有个控制终端,如果控制终端不存在,BusyBox的sh会报错。 2、runlevel_ignored 由该字段的名称可知,BusyBox init忽略runlevel_ignored字段,所以配置inittab时空着它就行了。 4、command command字段用来指定要执行命令(含路径),包括命令行选项。 3、action 在BusyBox-1.11.1中init.c定义了以下8种action
static const char actions[] = |
#define STR_SYSINIT "\x01" |
action | 含义 |
sysinit | 为init提供初始化命令脚本的路径 |
respawn | 每当相应的进程终止执行时,重新启动该进程 |
askfirst | 类似respawn,主要用途是减少系统上执行的终端应用程序的数量。它将会促使init在控制台上显示“Please press Enter to active this console”的信息,并在重新启动进程之前等待用户按下“enter”键 |
wait | 告诉init必须等到相应的进程执行完成之后才能继续执行 |
once | 仅执行相应的进程一次,而且不会等待它执行完成 |
ctratldel | 当按下Ctrl+Alt+Delete组合键时,执行相应的进程 |
shutdown | 当系统关机时,执行相应的进程 |
restart | 当init重新启动时,执行相应的进程,通常此处所执行的进程就是init本身 |
/* Set up a linked list of init_actions, to be read from inittab */
/* inittab文件的每一行都会保存为一个init_action节点,并且所有 init_action节点会被链接成一个叫init_action_list的列表*/ |
if (ENABLE_FEATURE_USE_INITTAB) |
//循环获取inittab文件中的每一行到buf中 while (fgets(buf, COMMAND_SIZE, file) != NULL) {
//定义action的种类
/*通过跳过空格,并截取到换行\n为止,来获取本行的有效内容,并保存于id中*/
//若为注释,跳出本次循环
//获取runlev字段
//获取action字段
//获取command字段
/*循环遍历actions数组,查找数组中与action字段相同的元素。找到后,通过new_init_action方法,将该元素的第一个字符(即action_type编码)和id及command字段作为一init_action节点添加到init_action_list列表中。接着跳到下一行进行处理*/
//查到数组actions中与action字段相同的元素 *runlev = '\0';
//若id字段非空
//若id字段带前缀/dev/,先截掉该前缀
//复制字符串/dev/到tmpConsole临时缓存区中
/*再将id字段复制到tmpConsole第5个字符之后,即/dev/之后。这样tmpConsole就成为了某一设备文件名(含路径)。对于BusyBox init来说,tmpConsole是终端设备*/
/*来到这里,应该就明白为什么BusyBox init的id字段是控制终端*/
//将action_type、command和控制终端id作为一init_action节点,添加到init_action_list列表中。从这里可以看出BusyBox init忽略了runlevel字段 |
/* Run all commands of a particular type */
//查到类型为action_type的节点
/*action_type为ONCE的init_action,init则不会等待它执行完,并且将该节点从init_action_list中删除*/
/*当action_type为RESOAWN或ASKFIRST的init_action,且执行该init_action的command的进程已死(通过a->pid == 0判断,已死RESOAWN或ASKFIRST的command进程,其init_action的pid域都会在init_main方法被置为0,具体见本文最后一段源码)时,调用run方法fork一子进程(用于执行command),并将run返回的子进程ID保存于init_action的pid域*/ |
/* Now run everything that needs to be run */ |
转自:http://blog.chinaunix.net/u3/109117/showart_2208026.html