最重要的一个service是zygote,之后的博文均以zygote为例讲解service。
上篇讲到init_parser.c中parse_new_section函数中根据关键字service可以开始对service的处理。处理函数为parse_service()和parse_line_service().
在看这两个函数之前,首先看下init.rc中对zygote service的section:
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
其中socket句创建一个名为zygote的TCP SOCKET,读写权限为666.
后面紧跟了四个onrestart语句,表明是在zygote服务重启时操作的。zygote如何重启请参照另一篇博文《android启动过程详解(三)——zygote的启动和重启》。
接下来需要有对应的结构来描述整个service和后面的四个onrestart。
init.h中:使用的结构体service来描述整个service。此结构体中包含一个声明:
struct action onrestart;
这个声明的作用就是使用action结构体来描述刚才解析文件中的onrestart部分。
init.h中:使用结构体action来描述后面的onrestart。可以看到里面包含一个声明:
struct listnode commands;(listnode用来将结构体链接成一个双向链表。)
对应zygote,它有四个onrestart,因此对应会创建四个command结构体。
了解了如何描述整个service之后,我们看解析service需要的两个函数。
init_parse.c中:parse_service()函数声明了一个service结构体,做简单的初始化操作,给这个service“搭了个架子”,搭好架子的service返回。
init_parse.c中:parse_line_service()函数完成具体的内容填充。根据解析文件init.rc中service的option,执行对应option下定义的操作,从而填充这个由parse_service()返回的service。具体到zygote,它的option就是onrestart,那么就执行switch case下对应的onrestart的内容:创建command结构体并初始化,把这个command加入到命令列表中。
对service的解析完成后,会达到以下效果:
-service_list链表将解析后的service全部链接到一起,双向链表。
-socketinfo(init.h中声明的service结构体中有一个变量,是socketinfo结构体声明的指针sockets
),这个指针指向所有本service的socket,双向链表。zygote只有一个socket,就是上面介绍的名为zygote的TCP SOCKET,读写权限为666.
-onrestart(init.h中声明的service结构体中有一个变量,是action结构体声明的onrestart,上面介绍过的),它指向一个command链表,双向链表。zygote的onrestart就指向一个有四个命令的command链表。
到此为止,init完成了对zygote服务的解析,其他服务的解析也类似。我们可以看到,解析服务只是完成了对这个service的“填充”操作,并没有真正的启动这项服务。启动、重启服务请参照博文《android启动过程详解——zygote的启动和重启》。