*该文件主要的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
//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]; };socket的结构体如下:
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; };*回到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);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;
//解析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();
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");最后,进入下一轮循环 重新启动SVC_RESTARTING的服务
//执行循环的动作 drain_action_queue(); //重启死去的进程 restart_processes();
*执行属性服务的过程总的有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请求即可对属性进行存储。