积累系统性知识
积聚技术精华
  首页    个人中心    撰写积文    建立课题    订立目标    整理积文    管理课题    管理目标    技能Get    代码积累 
Android2.2_INIT进程
error997 (error997)    2015-05-10 19:11:13      目标    课题
   1.init主要工作流程:
>解析两个配置文件.1个是 init.rc 1个是 init.hardware.rc
>执行各种Action,分别是early-init init early-boot boot
>调用property_init初始化属性 调用property_set设置属性 调用start_property_service启动属性服务
>init无限循环处理来自socket事件 属性事件


*附属工作:
>创建文件夹 挂载设备
>重定向输入/日至
>创建Uevent与Linux交互的socket
>初始化keychord调试设备
>socketpair创建两个socket
>init循环中 监听以上创建好代码的事件


2.解析配置文件:
>init.rc配置主要内容:
*该文件由3个flags标示区别开,分别是OPTION COMMAND SECTION ,SECTION表示章节(从关键字开始到下个关键字开始),
COMMAND表示执行动作,#define KEYWORD(symbol, flags, nargs, func) K_##symbol  当KEYWORD 的flags为COMMAND时执行func函数
   *该文件主要的section有on init,on boot分别对应4个执行动作中的两个.service zygote,service media分别对应两个service
   >分析zygote service配置解析
   *init.rc中的zygote信息(1个socket option 用于创建socket通讯和 3个onrestart option)

切换到: 纯代码  
   
# 一个service的section,对应的section 名为zygote  
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server  
    #socket onrestart是OPTION ,write restart是COMMAND  
    socket zygote stream 666  
    onrestart write /sys/android_power/request_state wake  
    onrestart write /sys/power/state on  
    onrestart restart media


   # 一个service的section,对应的section 名为zygote
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
   #socket onrestart是OPTION ,write restart是COMMAND
    socket zygote stream 666
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart media
   *回到init.c的 main函数中,调用parse_config_file("/init.rc");最终调用到Parser.c的parse_new_section(),如下

切换到: 纯代码  
   
//parse_service  parse_line_service 解析service   
        state->context = parse_service(state, nargs, args);  
        if (state->context) {  
            state->parse_line = parse_line_service;  
            return;  
        }


   //parse_service  parse_line_service 解析service
        state->context = parse_service(state, nargs, args);
        if (state->context) {
            state->parse_line = parse_line_service;
            return;
        }
   *解析zygote无非做两件事:1.解析socket配置环境 2.解析onrestart配置环境,而zygote本身的信息由函数parse_service()解析,
   而上面的两件事由parse_line_service()解析.解析前先查看zygote的结构体信息.

切换到: 纯代码  
   
struct service {  
    //双向链表, 用来保存解析配置文件后得到的service   
    struct listnode slist;  
  
  
    const char *name;   //service的名称   
    const char *classname;  //service的class名字,默认"default"   
  
  
    unsigned flags;  
    pid_t pid;        
    time_t time_started;    /* time of last start */  
    time_t time_crashed;    /* first crash within inspection window */  
    int nr_crashed;         /* number of times crashed within window */  
      
    uid_t uid;  
    gid_t gid;    
    gid_t supp_gids[NR_SVC_SUPP_GIDS];  
    size_t nr_supp_gids;  
  
    //读写权限为666 的 http socket, socket 也是IPC 通讯   
    struct socketinfo *sockets;  
    //描述进程所需环境变量信息   
    struct svcenvinfo *envvars;  
  
    //存储onrestart 后面的 COMMAND 信息   
    struct action onrestart;  /* Actions to execute on restart. */  
      
    /* keycodes for triggering this service via /dev/keychord */  
    int *keycodes;  
    int nkeycodes;  
    int keychord_id;  
  
    int ioprio_class;  
    int ioprio_pri;  
    int nargs;  
    char *args[1];  
};


   struct service {
    //双向链表, 用来保存解析配置文件后得到的service
    struct listnode slist;


    const char *name;   //service的名称
    const char *classname;   //service的class名字,默认"default"


    unsigned flags;
    pid_t pid;      
    time_t time_started;    /* time of last start */
    time_t time_crashed;    /* first crash within inspection window */
    int nr_crashed;         /* number of times crashed within window */
    
    uid_t uid;
    gid_t gid;   
    gid_t supp_gids[NR_SVC_SUPP_GIDS];
    size_t nr_supp_gids;

   //读写权限为666 的 http socket, socket 也是IPC 通讯
    struct socketinfo *sockets;
   //描述进程所需环境变量信息
    struct svcenvinfo *envvars;

   //存储onrestart 后面的 COMMAND 信息
    struct action onrestart;  /* Actions to execute on restart. */
    
    /* keycodes for triggering this service via /dev/keychord */
    int *keycodes;
    int nkeycodes;
    int keychord_id;

    int ioprio_class;
    int ioprio_pri;
    int nargs;
    char *args[1];
};
   socket的结构体如下:

切换到: 纯代码  
   
struct socketinfo {  
    struct socketinfo *next;  
    const char *name;  
    const char *type;  
    uid_t uid;  
    gid_t gid;  
    int perm;  
};


   struct socketinfo {
    struct socketinfo *next;
    const char *name;
    const char *type;
    uid_t uid;
    gid_t gid;
    int perm;
};
   onrestart的结构体如下:

切换到: 纯代码  
   
struct action {  
        /* node in list of all actions */  
    struct listnode alist;  
        /* node in the queue of pending actions */  
    struct listnode qlist;  
        /* node in list of actions for a trigger */  
    struct listnode tlist;  
  
    unsigned hash;  
    const char *name;  
    //zygote 配置文件有3发onrestart  option 对应3 个COMMAND 的双向链表   
    struct listnode commands;  
    struct command *current;  
};


   struct action {
        /* node in list of all actions */
    struct listnode alist;
        /* node in the queue of pending actions */
    struct listnode qlist;
        /* node in list of actions for a trigger */
    struct listnode tlist;

    unsigned hash;
    const char *name;
    //zygote 配置文件有3发onrestart  option 对应3 个COMMAND 的双向链表
    struct listnode commands;
    struct command *current;
};
   *回到Parser.c查看如何解析service主要结构体,parse_service()主要代码如下:

切换到: 纯代码  
   
svc = calloc(1, sizeof(*svc) + sizeof(char*) * nargs);  
    if (!svc) {  
        parse_error(state, "out of memory\n");  
        return 0;  
    }  
    svc->name = args[1];  
    svc->classname = "default";//设置classname 为"default"   
    memcpy(svc->args, args + 2, sizeof(char*) * nargs);  
    svc->args[nargs] = 0;  
    svc->nargs = nargs;  
    svc->onrestart.name = "onrestart";  
    list_init(&svc->onrestart.commands);  
    //把zygote 的service 加到 service_slist 全局链表中去.   
    list_add_tail(&service_list, &svc->slist);


   svc = calloc(1, sizeof(*svc) + sizeof(char*) * nargs);
    if (!svc) {
        parse_error(state, "out of memory\n");
        return 0;
    }
    svc->name = args[1];
    svc->classname = "default";//设置classname 为"default"
    memcpy(svc->args, args + 2, sizeof(char*) * nargs);
    svc->args[nargs] = 0;
    svc->nargs = nargs;
    svc->onrestart.name = "onrestart";
    list_init(&svc->onrestart.commands);
   //把zygote 的service 加到 service_slist 全局链表中去.
    list_add_tail(&service_list, &svc->slist);
   parse_line_service()主要代码如下:

切换到: 纯代码  
   
//创建socket相关信息并添加到zygote service 结构体中   
        si = calloc(1, sizeof(*si));  
        if (!si) {  
            parse_error(state, "out of memory\n");  
            break;  
        }  
        si->name = args[1];  
        si->type = args[2];  
        si->perm = strtoul(args[3], 0, 8);  
        if (nargs > 4)  
            si->uid = decode_uid(args[4]);  
        if (nargs > 5)  
            si->gid = decode_uid(args[5]);  
        si->next = svc->sockets;  
        svc->sockets = si;


   //创建socket相关信息并添加到zygote service 结构体中
        si = calloc(1, sizeof(*si));
        if (!si) {
            parse_error(state, "out of memory\n");
            break;
        }
        si->name = args[1];
        si->type = args[2];
        si->perm = strtoul(args[3], 0, 8);
        if (nargs > 4)
            si->uid = decode_uid(args[4]);
        if (nargs > 5)
            si->gid = decode_uid(args[5]);
        si->next = svc->sockets;
        svc->sockets = si;

切换到: 纯代码  
   
//解析onrestart 里面的配置信息并存储到service中去   
        cmd = malloc(sizeof(*cmd) + sizeof(char*) * nargs);  
        cmd->func = kw_func(kw);  
        cmd->nargs = nargs;  
        memcpy(cmd->args, args, sizeof(char*) * nargs);  
        list_add_tail(&svc->onrestart.commands, &cmd->clist);


   //解析onrestart 里面的配置信息并存储到service中去
        cmd = malloc(sizeof(*cmd) + sizeof(char*) * nargs);
        cmd->func = kw_func(kw);
        cmd->nargs = nargs;
        memcpy(cmd->args, args, sizeof(char*) * nargs);
        list_add_tail(&svc->onrestart.commands, &cmd->clist);
   至此,zygote解析如下图:
   3.创建zygote服务
   *解析完配置文件后 执行init.rc 中 on boot的所有 COMMAND;

切换到: 纯代码  
   
action_for_each_trigger("boot", action_add_queue_tail);  
      
    //#class_start是一个COMMAND 对应一个do_class_start函数   
    //执行所有on boot  section 节里面的COMMAND .   
    drain_action_queue();


   action_for_each_trigger("boot", action_add_queue_tail);
   
   //#class_start是一个COMMAND 对应一个do_class_start函数
    //执行所有on boot  section 节里面的COMMAND .
    drain_action_queue();

切换到: 纯代码  
   
int do_class_start(int nargs, char **args)  
{  
    //判断classname 第一次为default,执行service_start_if_not_disabled();   
    service_for_each_class(args[1], service_start_if_not_disabled);  
    return 0;  
}


   int do_class_start(int nargs, char **args)
{
    //判断classname 第一次为default,执行service_start_if_not_disabled();
    service_for_each_class(args[1], service_start_if_not_disabled);
    return 0;
}
   *触发
   do_class_start,实际上调用到
   service_start(),
   代码如下:
   该方法执行了如下步骤:
   1)判断zygote所在进程文件system/bin/app_process是否存在.
2)fork一条子进程
3)添加环境变量socket变量信息
   4)execve () 执行/system/bin/app_process  这样就进入到app_process的main中
5)修改服务信息
   4.重启zygote服务
   *当zygote服务进程销毁后,会调用sigchld_handler()往socket中写入数据,该socket由socketpair创建,
   此时另一条socket就能poll到数据,而执行wait_for_one_process处理事件,主要代码如下:

切换到: 纯代码  
   
//找到zygote 所在的service   
svc = service_find_by_pid(pid);  
if (!(svc->flags & SVC_ONESHOT)) {  
        //杀掉所有子进程   
        kill(-pid, SIGKILL);  
        NOTICE("process '%s' killing any children in process group\n", svc->name);  
    }  
  
  
    //清理socket信息   
    for (si = svc->sockets; si; si = si->next) {  
        char tmp[128];  
        snprintf(tmp, sizeof(tmp), ANDROID_SOCKET_DIR"/%s", si->name);  
        unlink(tmp);  
    }  
//设置标示为SVC_RESTARTING   
    svc->flags |= SVC_RESTARTING;  
  
  
    //执行onrestart  的内容   
    list_for_each(node, &svc->onrestart.commands) {  
        cmd = node_to_item(node, struct command, clist);  
        cmd->func(cmd->nargs, cmd->args);  
    }  
    //设置init.svc.zygote 值得为restarting   
    notify_service_state(svc->name, "restarting");


   //找到zygote 所在的service
svc = service_find_by_pid(pid);
if (!(svc->flags & SVC_ONESHOT)) {
      //杀掉所有子进程
        kill(-pid, SIGKILL);
        NOTICE("process '%s' killing any children in process group\n", svc->name);
    }


    //清理socket信息
    for (si = svc->sockets; si; si = si->next) {
        char tmp[128];
        snprintf(tmp, sizeof(tmp), ANDROID_SOCKET_DIR"/%s", si->name);
        unlink(tmp);
    }
//设置标示为SVC_RESTARTING
    svc->flags |= SVC_RESTARTING;


    //执行onrestart  的内容
    list_for_each(node, &svc->onrestart.commands) {
        cmd = node_to_item(node, struct command, clist);
        cmd->func(cmd->nargs, cmd->args);
    }
   //设置init.svc.zygote 值得为restarting
    notify_service_state(svc->name, "restarting");
   最后,进入下一轮循环 重新启动SVC_RESTARTING的服务

切换到: 纯代码  
   
//执行循环的动作   
drain_action_queue();  
//重启死去的进程   
 restart_processes();


   //执行循环的动作
drain_action_queue();
//重启死去的进程
 restart_processes();
   5.属性服务
   *执行属性服务的过程总的有2个,property_init()和start_property_service()
   *property_init()主要做了以下几件事
   1)创建共享内存
   2)创建共享内存到本地进程的映射
   *start_property_service()主要做了如下2件事
   1)加载持久化数据到property内存中
   2)创建socket的IPC通讯以便客户端传输数据
   *服务端如何获取数据,在init.c的main函数中,handle_property_set_fd函数等待客户端请求以便处理请求。它主要执行了如下几件事
   1)接收TCP连接
   2)接收请求数据
   3)"控制"消息处理
   4)调用property_set 设置属性,其中ro.* properties 为只读属性,net.change 特殊处理 持久化属性持久到特定的文件中等...
   *而对于客户端 只需要发送socket请求即可对属性进行存储。

转自 http://blog.csdn.net/qq285016127/article/details/42455611
(+0)技能Get

建议楼主:搜索关键字 |参考其他资源 |回复 |追问
  error997(error997):   个人中心    课题    目标    代码积累