上文讲到对服务的解析。说到底,“解析”只是填充这个服务的结构体。service在生存、运行、死亡过程中,需要根据service结构体中的信息做一些相关操作。本节就以zygote为例,讲述service是如何启动和重启的。
一 启动
init.rc中的boot section有一句话:
class_start default
表示启动所有default组的服务。zygote就是default组的。
如何启动呢?
class_start是一个command,对应的处理函数式do_class_start(keywords.h中定义,对于androidkeywords.h的使用技巧,网上有一些文章,这里不再赘述)。
因此,在init.c的main函数将boot section的command加入到执行队列,然后执行到class_start这一步骤时,就会调用对应的do_class_start()函数了。
system/core/init/builtins.c中:do_class_start()函数调用了service_for_each_class()函数。这个函数就是从service_list中找到classname为default的service,然后调用service_start_if_not_disabled()函数。
bulitins.c中:service_start_if_not_disabled()函数调用service_start()函数。
init.c中:service_start()函数的主要步骤包括:首先判断zygote对应的可执行文件是否存在。然后调用fork创建子进程。在子进程中得到属性存储空间的信息并加到环境变量中。设置uid、gid等。使用execve执行这个zygote对应的可执行文件。在父进程中设置service的信息。
二 重启
重启时就会用到上篇日志提到的onrestart了!
zygote死后,父进程init会调用signal_handler.c中的sigchld_handler()处理,这个函数向信号signal_fd发送数据。接下来我们需要知道谁来接收数据。
init.c中:调用handle_signal()函数的部分就是接收数据的部分。
signal_handle.c中:handle_signal()函数调用了wait_for_one_process()函数处理。
signal_handler.c中:wait_for_one_process()函数首先等待退出的子进程,返回这个进程号。得到的进程号就是已经死掉的zygote service。之后清理socket信息。根据service的标识做相应的操作。执行service onrestart中的相应操作。最后设置这个service为restart状态。
在init.c的main函数中,有restart_process()函数。这个函数的功能就是重启所有标志为restart状态的service。此时,zygote重启成功。