前面已经讲解了对配置文件的解析,将所有的on和service都解析成对应的action和service结构体,并且保存在action_list和service_list链表中,接下来就讲解action
被添加到action_queue中被init进程执行的过程。
action_for_each_trigger("early-init", action_add_queue_tail);
queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done");
queue_builtin_action(property_init_action, "property_init");
queue_builtin_action(keychord_init_action, "keychord_init");
queue_builtin_action(console_init_action, "console_init");
queue_builtin_action(set_init_properties_action, "set_init_properties");
/* execute all the boot actions to get us started */
action_for_each_trigger("init", action_add_queue_tail);
/* skip mounting filesystems in charger mode */
if (strcmp(bootmode, "charger") != 0) {
action_for_each_trigger("early-fs", action_add_queue_tail);
action_for_each_trigger("fs", action_add_queue_tail);
action_for_each_trigger("post-fs", action_add_queue_tail);
action_for_each_trigger("post-fs-data", action_add_queue_tail);
}
queue_builtin_action(property_service_init_action, "property_service_init");
queue_builtin_action(signal_init_action, "signal_init");
queue_builtin_action(check_startup_action, "check_startup");
if (!strcmp(bootmode, "charger")) {
action_for_each_trigger("charger", action_add_queue_tail);
} else {
action_for_each_trigger("early-boot", action_add_queue_tail);
action_for_each_trigger("boot", action_add_queue_tail);
}
/* run all property triggers based on current state of the properties */
queue_builtin_action(queue_property_triggers_action, "queue_propety_triggers");
#if BOOTCHART
queue_builtin_action(bootchart_init_action, "bootchart_init");
#endif
action_for_each_trigger函数是将名为参数1的action添加到action_queue尾部。
queue_builtin_action函数是构建一个名为参数2的action以及一个参数1的command,并将command添加到action的commands链表中,最后将action添加到action_list
和action_queue的尾部。看到这里似乎所有的action都添加到了action_queue链表中,但仔细看配置文档会发现一些奇怪的action:
on property:vold.decrypt=trigger_reset_main
class_reset main
on property:vold.decrypt=trigger_restart_min_framework
class_start main
on property:vold.decrypt=trigger_restart_framework
class_start main
class_start late_start
on property:vold.decrypt=trigger_shutdown_framework
class_reset late_start
class_reset main
on property:sys.usb.config=adb
start adbd
on property:sys.usb.config=accessory,adb
start adbd
on property:ro.debuggable=1
start console
on property:ro.kernel.qemu=1
start adbd
这些action的名字都是以"property:"为前缀,后面跟着名值对,很显然前面没将这样的action添加到action_queue中,好了不卖光子了,前面调用了一个函数:
queue_builtin_action(queue_property_triggers_action, "queue_propety_triggers");当这个函数创建的action的命令执行时,就会调用queue_property_triggers_action
函数,这个函数会将所有property:开头的action进行处理,当名值对中名字表示的属性在系统属性中的值为名值对中的值或*号时,就将该action添加到action_queue中。
好了,所有action都添加到action_queue中等待执行了,但前面解析出来的service什么时候启动的呢?
on early-init
start ueventd
on boot
class_start core
class_start main
on nonencrypted
class_start late_start
on charger
class_start charger
看上面几个action,会发现这些action中的command都是以start和class_start开头,这两个command分别调用函数do_start和do_class_start:
int do_start(int nargs, char **args)
{
struct service *svc;
svc = service_find_by_name(args[1]);
if (svc) {
service_start(svc, NULL);
}
return 0;
}
int do_class_start(int nargs, char **args)
{
/* Starting a class does not start services
* which are explicitly disabled. They must
* be started individually.
*/
service_for_each_class(args[1], service_start_if_not_disabled);
return 0;
}
static void service_start_if_not_disabled(struct service *svc)
{
if (!(svc->flags & SVC_DISABLED)) {
service_start(svc, NULL);
}
}
do_start是启动args[1]表示的service,do_class_start是启动args[1]这一类service。
init进程会调用一个restart_processes()函数,这个函数主要是启动状态为SVC_RESTARTING的service,但是service的状态什么时候变成SVC_RESTARTING的呢?
这里不卖光子,直接解释:任何service进程都是init进程的子进程,当service进程挂掉后,都会向init进程发送信号,下面来看init进程中信号处理函数handle_signal():
void handle_signal(void)
{
char tmp[32];
/* we got a SIGCHLD - reap and restart as needed */
read(signal_recv_fd, tmp, sizeof(tmp));
while (!wait_for_one_process(0))
;
}
在wait_for_one_process函数中会通过pid获取挂掉的service,并将其状态设置成SVC_RESTARTING(svc->flags |= SVC_RESTARTING),这样上面
restart_processes()方法就可以将其重启。在wait_for_one_process函数中还会执行service中onrestart表示的命令,这些命令一般是重启其他service。
关于事件处理这里不多介绍,有兴趣的可以自己研究。
被添加到action_queue中被init进程执行的过程。
action_for_each_trigger("early-init", action_add_queue_tail);
queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done");
queue_builtin_action(property_init_action, "property_init");
queue_builtin_action(keychord_init_action, "keychord_init");
queue_builtin_action(console_init_action, "console_init");
queue_builtin_action(set_init_properties_action, "set_init_properties");
/* execute all the boot actions to get us started */
action_for_each_trigger("init", action_add_queue_tail);
/* skip mounting filesystems in charger mode */
if (strcmp(bootmode, "charger") != 0) {
action_for_each_trigger("early-fs", action_add_queue_tail);
action_for_each_trigger("fs", action_add_queue_tail);
action_for_each_trigger("post-fs", action_add_queue_tail);
action_for_each_trigger("post-fs-data", action_add_queue_tail);
}
queue_builtin_action(property_service_init_action, "property_service_init");
queue_builtin_action(signal_init_action, "signal_init");
queue_builtin_action(check_startup_action, "check_startup");
if (!strcmp(bootmode, "charger")) {
action_for_each_trigger("charger", action_add_queue_tail);
} else {
action_for_each_trigger("early-boot", action_add_queue_tail);
action_for_each_trigger("boot", action_add_queue_tail);
}
/* run all property triggers based on current state of the properties */
queue_builtin_action(queue_property_triggers_action, "queue_propety_triggers");
#if BOOTCHART
queue_builtin_action(bootchart_init_action, "bootchart_init");
#endif
action_for_each_trigger函数是将名为参数1的action添加到action_queue尾部。
queue_builtin_action函数是构建一个名为参数2的action以及一个参数1的command,并将command添加到action的commands链表中,最后将action添加到action_list
和action_queue的尾部。看到这里似乎所有的action都添加到了action_queue链表中,但仔细看配置文档会发现一些奇怪的action:
on property:vold.decrypt=trigger_reset_main
class_reset main
on property:vold.decrypt=trigger_restart_min_framework
class_start main
on property:vold.decrypt=trigger_restart_framework
class_start main
class_start late_start
on property:vold.decrypt=trigger_shutdown_framework
class_reset late_start
class_reset main
on property:sys.usb.config=adb
start adbd
on property:sys.usb.config=accessory,adb
start adbd
on property:ro.debuggable=1
start console
on property:ro.kernel.qemu=1
start adbd
这些action的名字都是以"property:"为前缀,后面跟着名值对,很显然前面没将这样的action添加到action_queue中,好了不卖光子了,前面调用了一个函数:
queue_builtin_action(queue_property_triggers_action, "queue_propety_triggers");当这个函数创建的action的命令执行时,就会调用queue_property_triggers_action
函数,这个函数会将所有property:开头的action进行处理,当名值对中名字表示的属性在系统属性中的值为名值对中的值或*号时,就将该action添加到action_queue中。
好了,所有action都添加到action_queue中等待执行了,但前面解析出来的service什么时候启动的呢?
on early-init
start ueventd
on boot
class_start core
class_start main
on nonencrypted
class_start late_start
on charger
class_start charger
看上面几个action,会发现这些action中的command都是以start和class_start开头,这两个command分别调用函数do_start和do_class_start:
int do_start(int nargs, char **args)
{
struct service *svc;
svc = service_find_by_name(args[1]);
if (svc) {
service_start(svc, NULL);
}
return 0;
}
int do_class_start(int nargs, char **args)
{
/* Starting a class does not start services
* which are explicitly disabled. They must
* be started individually.
*/
service_for_each_class(args[1], service_start_if_not_disabled);
return 0;
}
static void service_start_if_not_disabled(struct service *svc)
{
if (!(svc->flags & SVC_DISABLED)) {
service_start(svc, NULL);
}
}
do_start是启动args[1]表示的service,do_class_start是启动args[1]这一类service。
init进程会调用一个restart_processes()函数,这个函数主要是启动状态为SVC_RESTARTING的service,但是service的状态什么时候变成SVC_RESTARTING的呢?
这里不卖光子,直接解释:任何service进程都是init进程的子进程,当service进程挂掉后,都会向init进程发送信号,下面来看init进程中信号处理函数handle_signal():
void handle_signal(void)
{
char tmp[32];
/* we got a SIGCHLD - reap and restart as needed */
read(signal_recv_fd, tmp, sizeof(tmp));
while (!wait_for_one_process(0))
;
}
在wait_for_one_process函数中会通过pid获取挂掉的service,并将其状态设置成SVC_RESTARTING(svc->flags |= SVC_RESTARTING),这样上面
restart_processes()方法就可以将其重启。在wait_for_one_process函数中还会执行service中onrestart表示的命令,这些命令一般是重启其他service。
关于事件处理这里不多介绍,有兴趣的可以自己研究。