3.5.3 启动Service
从init.c的main函数中只看到了Action的触发和执行,似乎并没有找到Service启动的痕迹。这个不难,在上一节分析early-init的时候出现了service_start函数,它是专门用来启动Service的,只需要找出谁调用了它,就能找到Service是在哪里启动的。定位到service_start_if_not_disabled函数,其位于builtins.c中,代码如下:
static void service_start_if_not_disabled(struct service*svc)
{
if(!(svc->flags&SVC_DISABLED)){
service_start(svc, NULL);
}
}
service_start_if_not_disabled也是根据传入的service结构体调用service_start的,这不是最终目标。继续定位service_start_if_not_disabled的调用者,找到do_class_start函数,其依然位于builtins.c中,代码如下:
int do_class_start(int nargs, char**args)
{
service_for_each_class(args[1],service_start_if_not_disabled);
return 0;
}
这个函数不就是keywords.h中定义的class_start这个Command所对应的函数吗?
keywords. h中的定义如下:
KEYWORD(class_start, COMMAND,1,do_class_start)
原来只要运行了class_start这个Command,就会启动相应的Service。所以,接下来,只需要在init.rc中找到哪里执行了class_start这个Command,就知道Service是在哪里启动了。init.rc中的很多Action都执行了class_start这个Command,选择在启动阶段触发并且在init.rc中配置过的Action。其中Trigger为boot的Action满足条件,其代码如下:
on boot
……//省略其他Command
/*core和main是Service的分类名,这里将启动所有在
Option中配置了class core和class main的Service/
class_start core
class_start main
原来在init的main方法中,执行到action_for_each_trigger("boot",action_add_queue_tail),在触发boot Action的过程中,将要启动的Service与Command关联起来的。可见,init是把Service作为一个进程,用Command启动的,这样所有Service便是init的子进程了。这些由init启动的Service主要有:ueventd、servicemanager、vold、zygote、installd、ril-daemon、debuggerd、bootanim(显示开机动画)等,通常称这些Service为守护进程服务(Daemon Service)。
到这里Action和Service的启动就分析完了,下面分析init对属性服务的处理。