`

浅析kernel启动的第1个用户进程init如何解读init.rc脚本

 
阅读更多

浅析kernel启动的第1个用户进程init如何解读init. rc脚本

首先解读
1. on init字段到来, state- > context为新申请到的struct action结构体, 并将其挂接到action_list尾部, 然后初始化处理方法,
之后该section内的所有command都将挂接到act- > commands链表上, 这样也就有了立体层次[ luther. gliethttp] .
state- > parse_line = parse_line_action; 这样以后的"行脚本" 将使用这个方法来做处理.
2. loglevel 3因为为cmd,
所以会将动态malloc一个struct command缓冲区,
cmd = malloc ( sizeof ( * cmd) + sizeof ( char * ) * nargs) ;
cmd- > func = kw_func( kw) ;
cmd- > nargs = nargs;
memcpy ( cmd- > args, args, sizeof ( char * ) * nargs) ;
list_add_tail( & act- > commands, & cmd- > clist) ; //先将cmd结构体放到list链表尾,后面会集中处理.
3. 之后就都是上面的重复工作了.

一个on和一个service都将创建一个新的struct action结构体, 之后作为当前state- > context来处理接下来的所有cmd,
所以接下来的所有cmd也就都将挂接到这个新的act- > commands链表上, 感觉这样一来脚本非常有层次感, 管理起来也很舒服.
4. 对于service服务段处理, 如果为service命令, 那么, 先检查service_list链表上是否已经有了同名的服务[ luther. gliethttp] .
svc = service_find_by_name( args[ 1] ) ;
if ( svc) {
parse_error( state, "ignored duplicate definition of service '%s'/n" , args[ 1] ) ;
return 0;
}
svc = calloc ( 1, sizeof ( * svc) + sizeof ( char * ) * nargs) ;
if ( ! svc) {
parse_error( state, "out of memory/n" ) ;
return 0;
}
svc- > name = args[ 1] ;
svc- > classname = "default" ;
memcpy ( svc- > args, args + 2, sizeof ( char * ) * nargs) ;
svc- > args[ nargs] = 0;
svc- > nargs = nargs;
list_add_tail( & service_list, & svc- > slist) ; //将这个service控制结构体添加到service_list链表尾.
然后将paser的方法指向service方法
state- > parse_line = parse_line_service; //以下所有参数都将使用parse_line_service进行解析.
5. service命令后边的参数都将用来改变该service控制结构体里的项, 不同的service命令,
对args有不同的解析方式, 都在parse_line_service中完成, 比如:
1 service dund / system / bin/ dund /
2 - - listen - - channel= 5 - - nodetach - - pppd= / system / bin/ pppd /
3 192. 168. 0. 100: 192. 168. 0. 101 nodefaultroute unit 1 linkname bluetooth
4 user bluetooth
5 group bluetooth net_bt_admin
6 disabled
那么1行开始将申请一个service结构体, 然后挂接到service_list链表上,
之后的5行都是用来控制这个service结构体里边的数据项, 直到在行首遇到下一个service关键字或者on才会停止[ luther. gliethttp] .

好了, 基本的命令字和立体的脚本解析结构, 已经说完了, 那么从init. rc脚本解析出来的咚咚在啥时候用呢,

1. 对于on节提供的对外接口
void action_for_each_trigger( const char * trigger,
void ( * func) ( struct action * act) )
void queue_property_triggers( const char * name, const char * value)
void queue_all_property_triggers( )
举个例子
action_for_each_trigger( "early-init" , action_add_queue_tail) ;
action_for_each_trigger( "init" , action_add_queue_tail) ;
action_for_each_trigger( "early-boot" , action_add_queue_tail) ;
action_for_each_trigger( "boot" , action_add_queue_tail) ;
2. 对于service节提供的对外接口
struct service * service_find_by_name( const char * name)
struct service * service_find_by_pid( pid_t pid)
void service_for_each_class( const char * classname,
void ( * func) ( struct service * svc) )
void service_for_each_flags( unsigned matchflags,
void ( * func) ( struct service * svc) )
举个例子
int do_start( int nargs, char * * args)
{
struct service * svc;
svc = service_find_by_name( args[ 1] ) ;
if ( svc) {
service_start( svc) ;
}
return 0;
}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics