浅析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;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值