android源码系列:init分析2

来源:互联网 发布:什么是java序列化 编辑:程序博客网 时间:2024/05/17 02:36
前面已经讲解了对配置文件的解析,将所有的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。

关于事件处理这里不多介绍,有兴趣的可以自己研究。

0 0
原创粉丝点击