查看系统是怎么做到守护进程的
什么系统关键服务 系统的关键服务的ppid也就是父进程都是为1的
闹钟  LayoutInflater   WindowManager    不是    
网络服务,多媒体服务 ,音量服务,安装服务。 电话服务,adb服务  ,触摸事件服务  
netd  网络服务  封装了复杂的底层各种类型的网络
mediaservice   多媒体服务   手机开机需要声音,画面    
ueventd  屏幕响应事件的服务
ueventd  屏幕响应事件的服务
事件分发   activity ondispatchevent()
logd     日志服务
vold     外部存储设备服务  管理和控制Android平台外部存储设备,包括SD插拨、挂载、卸载、格式化等;
Rild     是电话系统的核心部分
进入adb shell 命令执行ps查看进程的消息
源码分析,我们这里采用的6.0的源码
首先我们知道,系统在启动的时候,首先会去加载一个文件,为init文件,利用as,可以查看到,可以发现他的权限是有x的,代表是一个可以执行的文件
init可以执行的文件是通过下面的源码路径来编译的  F:\AndroidSource\android-6.0.0_r1\android-6.0.0_r1\system\core ,core目录下面还有很多可以执行的文件比如adb
既然是一个可以执行的文件,那么肯定有一个文件还有main函数的入口,这里main函数的入口即为init.cpp文件中
int main(int argc, char** argv) {
    if (!strcmp(basename(argv[0]), "ueventd")) {
        return ueventd_main(argc, argv);
    }
    ......
    init_parse_config_file("/init.rc");
    .....
}
查看这个函数的实现 init_parse_config_file("/init.rc");
这个文件里面有很多类似这样的,来声明配置一个服务,
我们能不能获取root权限后  通过修改init.rc配置文件 启动 自己的服务呢?
 即使有了root权限,可以修改该文件也没有。因为我们在根目录看到的文件只是内存文件的镜像。也就是说,android启动后,会将init.rc文件装载到内存。
 而修改init.rc文件的内容实际上只是修改内存中的init.rc文件的内容。一旦重启android,init.rc文件的内容又会恢复到最初的装载。
 想彻底修改init.rc文件内容的唯一方式是修改Android的ROM中的内核镜像(boot.img)。其实boot.img名为内核镜像,有一个镜像ramdisk.img就包含了init.rc文件和init命令。
 所以只有修改ramdisk.img文件中的init.rc文件,并且重新打包boot.img文件,并刷机,才能彻底修改init.rc文件。将Android源代码,编译后,
 就会看到out目录中的相关子目录会生成一个root目录,该目录实际上就是ramdisk.img解压后的内容。会看到有init命令和init.rc文件。通过简单的修改init.rc文件是达不到的
service netd /system/bin/netd
    class main
    socket netd stream 0660 root system
    socket dnsproxyd stream 0660 root inet
    socket mdns stream 0660 root system
此函数中有 parse_config(path, data);
static void parse_config(const char *fn, const std::string& data)
{
    struct listnode import_list;
    struct listnode *node;
    ......
    for (;;) {
        switch (next_token(&state)) {
        case T_EOF:
            state.parse_line(&state, 0, 0);
            goto parser_done;
        case T_NEWLINE:
            state.line++;
            if (nargs) {
                int kw = lookup_keyword(args[0]);
                if (kw_is(kw, SECTION)) {
                    state.parse_line(&state, 0, 0);
                    parse_new_section(&state, kw, nargs, args);
                } else {
                    state.parse_line(&state, nargs, args);
                }
                nargs = 0;
            }
            break;
        case T_TEXT:
            if (nargs < INIT_PARSER_MAXARGS) {
                args[nargs++] = state.text;
            }
            break;
        }
    }
    ....
}
int kw = lookup_keyword(args[0]); 是根据第一个的字符,得到对应的函数 
比如init.rc文件中的
on nonencrypted
    class_start late_start
service drm /system/bin/drmserver
    class main
    user drm
    group drm system inet drmrpc
static int lookup_keyword(const char *s) 其中的s就代表的是第二行的内容 比如这里是 class_start class main 注意这里的class main 跟class_start是一样的
{
    switch (*s++) {
    case 'b':
        if (!strcmp(s, "ootchart_init")) return K_bootchart_init;
        break;
    case 'c':
        if (!strcmp(s, "opy")) return K_copy;
        if (!strcmp(s, "lass")) return K_class;
        if (!strcmp(s, "lass_start")) return K_class_start;
        if (!strcmp(s, "lass_stop")) return K_class_stop;
        if (!strcmp(s, "lass_reset")) return K_class_reset;
        if (!strcmp(s, "onsole")) return K_console;
        if (!strcmp(s, "hown")) return K_chown;
        if (!strcmp(s, "hmod")) return K_chmod;
        if (!strcmp(s, "ritical")) return K_critical;
        break
        ....
}
所以上面会返回一个K_class_start,而k_class_start为  KEYWORD(class_start, COMMAND, 1, do_class_start) 也就为 do_class_start,是一个函数指针
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;
}
然后执行 parse_new_section(&state, kw, nargs, args);
static void parse_new_section(struct parse_state *state, int kw,
                       int nargs, char **args)
{
    printf("[ %s %s ]\n", args[0],
           nargs > 1 ? args[1] : "");
    switch(kw) {
    case K_service:  对应的init.rc文件中的service开头的 
        state->context = parse_service(state, nargs, args);
        if (state->context) {
            state->parse_line = parse_line_service;
            return;
        }
        break;
    case K_on:   对应的init.rc 文件中的 on 开头的
        state->context = parse_action(state, nargs, args);
        if (state->context) {
            state->parse_line = parse_line_action;
            return;
        }
        break;
    case K_import:  对应的init.rc 文件中的 import 开头的
        parse_import(state, nargs, args);
        break;
    }
    state->parse_line = parse_line_no_op;
}
parse_service(state,nargs,args);函数实现
static void *parse_service(struct parse_state *state, int nargs, char **args)
{
    ......
    从service集合里面查找如果查找到了直接返回
    service* svc = (service*) service_find_by_name(args[1]);
    if (svc) {
        parse_error(state, "ignored duplicate definition of service '%s'\n", args[1]);
        return 0;
    }
    nargs -= 2;
    如果没有查找到就new 一个service 分配内存空间
    svc = (service*) calloc(1, sizeof(*svc) + sizeof(char*) * nargs);
    if (!svc) {
        parse_error(state, "out of memory\n");
        return 0;
    }
    给service 赋值
    svc->name = strdup(args[1]);
    svc->classname = "default";
    memcpy(svc->args, args + 2, sizeof(char*) * nargs);
    trigger* cur_trigger = (trigger*) calloc(1, sizeof(*cur_trigger));
    svc->args[nargs] = 0;
    svc->nargs = nargs;
    list_init(&svc->onrestart.triggers);
    cur_trigger->name = "onrestart";
    list_add_tail(&svc->onrestart.triggers, &cur_trigger->nlist);
    执行下面的代码就会给 serivce 中的action 中的 command 里面的  int (*func)(int nargs, char **args); 这个成员变量赋值为通过lookup_keyword 返回的那个函数指针
    list_init(&svc->onrestart.commands);
    list_add_tail(&service_list, &svc->slist);
    return svc;
}
解析完init.rc文件之后
init.rc main函数中还有这样的,下面的是用来解析不是配置在init.rc文件中的服务的
queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done"); 第一个参数就为一个函数指针
void queue_builtin_action(int (*func)(int nargs, char **args), const char *name)
{
    action* act = (action*) calloc(1, sizeof(*act));
    trigger* cur_trigger = (trigger*) calloc(1, sizeof(*cur_trigger));
    cur_trigger->name = name;
    list_init(&act->triggers);
    list_add_tail(&act->triggers, &cur_trigger->nlist);
    list_init(&act->commands);
    list_init(&act->qlist);
    command* cmd = (command*) calloc(1, sizeof(*cmd));
    给入口函数赋值
    cmd->func = func;
    cmd->args[0] = const_cast<char*>(name);
    cmd->nargs = 1;
    list_add_tail(&act->commands, &cmd->clist);
    添加到servic列表里面
    list_add_tail(&action_list, &act->alist);
    action_add_queue_tail(act);
}
等上面的serive所有都解析完之后,init main 函数中还有
 while (true) {
     if (!waiting_for_exec) {
            启动服务
            execute_one_command();
            restart_processes();
}
execute_one_command()中含有下面的代码,获取第一个的service,然后从这个service里面获取到第一个command,赋值给cur_command
if (!cur_action || !cur_command || is_last_command(cur_action, cur_command)) {
        cur_action = action_remove_queue_head();
        cur_command = NULL;
        if (!cur_action) {
            return;
        }
        build_triggers_string(name_str, sizeof(name_str), cur_action);
        INFO("processing action %p (%s)\n", cur_action, name_str);
        cur_command = get_first_command(cur_action);
    } else {
        cur_command = get_next_command(cur_action, cur_command);
    }
    然后执行这个函数,这个就会执行到解析到service里面的func 函数指针比如
    int result = cur_command->func(cur_command->nargs, cur_command->args);
比如上面的queue_builtin_action(keychord_init_action, "keychord_init"); 这里的func为,执行对应的函数的初始话操作
void keychord_init() {
    service_for_each(add_service_keycodes);
    // Nothing to do if no services require keychords.
    if (!keychords) {
        return;
    }
    keychord_fd = TEMP_FAILURE_RETRY(open("/dev/keychord", O_RDWR | O_CLOEXEC));
    if (keychord_fd == -1) {
        ERROR("could not open /dev/keychord: %s\n", strerror(errno));
        return;
    }
    int ret = write(keychord_fd, keychords, keychords_length);
    if (ret != keychords_length) {
        ERROR("could not configure /dev/keychord %d: %s\n", ret, strerror(errno));
        close(keychord_fd);
    }
    free(keychords);
    keychords = nullptr;
    register_epoll_handler(keychord_fd, handle_keychord);
}
执行 restart_processes();
static void restart_processes()
{
    process_needs_restart = 0;
    service_for_each_flags(SVC_RESTARTING,restart_service_if_needed);restart_service_if_needed 为函数指针
}
void service_for_each_flags(unsigned matchflags,
                            void (*func)(struct service *svc))
{
    struct listnode *node;
    struct service *svc;
    list_for_each(node, &service_list) {
        svc = node_to_item(node, struct service, slist);
        if (svc->flags & matchflags) {
            func(svc); 即会回调传递过来的函数指针,即restart_service_if_needed
        }
    }
}
函数指针的实现为
static void restart_service_if_needed(struct service *svc)
{
    time_t next_start_time = svc->time_started + 5;
    if (next_start_time <= gettime()) {
        svc->flags &= (~SVC_RESTARTING);
        service_start(svc, NULL); 开启服务
        return;
    }
    if ((next_start_time < process_needs_restart) ||
        (process_needs_restart == 0)) {
        process_needs_restart = next_start_time;
    }
}
  service_start(svc, NULL); 开启服务 函数实现
void service_start(struct service *svc, const char *dynamic_args)
{
 也是通过fork一个子进程,在子进程里面启动这个服务,至此服务被启动完成,这里没有看到守护进程的代码,这里需要了解的是
 fork一个进程 会让子进程跟父进程拥有同样的资源,所以可能父进程里面有处理
 pid_t pid = fork();
    if (pid == 0) {
        struct socketinfo *si;
        struct svcenvinfo *ei;
        char tmp[32];
        int fd, sz;
        char *arg_ptrs[INIT_PARSER_MAXARGS+1];
        int arg_idx = svc->nargs;
        char *tmp = strdup(dynamic_args);
        char *next = tmp;
        char *bword;
        /* Copy the static arguments */
        memcpy(arg_ptrs, svc->args, (svc->nargs * sizeof(char *)));
        while((bword = strsep(&next, " "))) {
                arg_ptrs[arg_idx++] = bword;
                if (arg_idx == INIT_PARSER_MAXARGS)
                    break;
         }
        rg_ptrs[arg_idx] = NULL;
        execve(svc->args[0], (char**) arg_ptrs, (char**) ENV);  通过这个可执行的命令启动一个服务execve
     }
}
在init.cpp 文件中的main方法中有这样的代码
    signal_handler_init();
    property_load_boot_defaults();
    start_property_service();
signal_handler_init(); 函数的实现
void signal_handler_init() {
    // Create a signalling mechanism for SIGCHLD.
    int s[2];
    这里创建俩个socket套接字,是一对来的,一个用来做客户端,一个用来做服务端
    if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0, s) == -1) {
        ERROR("socketpair failed: %s\n", strerror(errno));
        exit(1);
    }
    给全局的变量赋值
    signal_write_fd = s[0];
    signal_read_fd = s[1];
    // Write to signal_write_fd if we catch SIGCHLD.
    struct sigaction act;
    memset(&act, 0, sizeof(act));
    SIGCHLD_handlerw为一个函数指针,也即是当系统杀死调进程的时候,会回调执行的函数
    act.sa_handler = SIGCHLD_handler;
    act.sa_flags = SA_NOCLDSTOP;
    sigaction(SIGCHLD, &act, 0);
    reap_any_outstanding_children();
    注册监听
    register_epoll_handler(signal_read_fd, handle_signal);
}
handle_signal 为一个函数指针,函数的原型为
static void handle_signal() {
    // Clear outstanding requests.
    char buf[32];
    //从signal_read_fd读取内容,read 会阻塞
    read(signal_read_fd, buf, sizeof(buf));
    reap_any_outstanding_children();
}
register_epoll_handler函数的实现为
void register_epoll_handler(int fd, void (*fn)()) {
    epoll_event ev;
    ev.events = EPOLLIN;
    将fn 赋值给ev.data.ptr
    ev.data.ptr = reinterpret_cast<void*>(fn);
    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev) == -1) {
        ERROR("epoll_ctl failed: %s\n", strerror(errno));
    }
}
SIGCHLD_handler函数的原型为
static void SIGCHLD_handler(int) {
    这里利用 signal_write_fd 客户端的socket套接字直接的发消息,这样我们查看接受的地方
    if (TEMP_FAILURE_RETRY(write(signal_write_fd, "1", 1)) == -1) {
        ERROR("write(signal_write_fd) failed: %s\n", strerror(errno));
    }
}
main函数中的while循环中
epoll_event ev;
        int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, timeout));
        if (nr == -1) {
            ERROR("epoll_wait failed: %s\n", strerror(errno));
        } else if (nr == 1) {
            ((void (*)()) ev.data.ptr)(); 执行回调函数,也就是执行到了handle_signal 这个函数里面,这样当客户端收到了要关闭的进程之后,就主动的发了一个消息,这样服务端就接受到了
}
static void handle_signal() {
    // Clear outstanding requests.
    char buf[32];
    //从signal_read_fd读取内容,read 会阻塞
    read(signal_read_fd, buf, sizeof(buf));
    reap_any_outstanding_children();
}
然后执行reap_any_outstanding_children
static void reap_any_outstanding_children() {
    while (wait_for_one_process()) {
    }
}
wait_for_one_process()函数里面有这样的关键代码
 // Execute all onrestart commands for this service.
    struct listnode* node;
    list_for_each(node, &svc->onrestart.commands) {
        command* cmd = node_to_item(node, struct command, clist);
         执行入口函数
         cmd->func(cmd->nargs, cmd->args);
    }
    服务又再次的被启动
    svc->NotifyStateChange("restarting");
    return true;
然后main 中的while循环里面就会把这个服务启动    
方式二 main函数中有这样的代码
start_property_service();
函数原型实现
void start_property_service() {
    创建socket套接字
    property_set_fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
                                    0666, 0, 0, NULL);
    if (property_set_fd == -1) {
        ERROR("start_property_service socket creation failed: %s\n", strerror(errno));
        exit(1);
    }
    监听,8为并发数
    listen(property_set_fd, 8);
    注册监听
    register_epoll_handler(property_set_fd, handle_property_set_fd);handle_property_set_fd为一个函数指针
}
handle_property_set_fd 函数原型的实现为:
static void handle_property_set_fd()
{
    监听
    if ((s = accept(property_set_fd, (struct sockaddr *) &addr, &addr_size)) < 0) {
        return;
    }
    /* Check socket options here */
    if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cr, &cr_size) < 0) {
        close(s);
        ERROR("Unable to receive socket options\n");
        return;
    }
    ufds[0].fd = s;
    ufds[0].events = POLLIN;
    ufds[0].revents = 0;
    .......
     handle_control_message((char*) msg.name + 4, (char*) msg.value);
    .......
}
handle_control_message()函数原型实现
void handle_control_message(const char *msg, const char *arg)
{
    if (!strcmp(msg,"start")) {
        msg_start(arg); 启动服务
    } else if (!strcmp(msg,"stop")) {
        msg_stop(arg);
    } else if (!strcmp(msg,"restart")) {
        msg_restart(arg);
    } else {
        ERROR("unknown control msg '%s'\n", msg);
    }
}
启动服务
static void msg_start(const char *name)
{
    struct service *svc = NULL;
    char *tmp = NULL;
    char *args = NULL;
    if (!strchr(name, ':'))
        svc = service_find_by_name(name);
    else {
        tmp = strdup(name);
        if (tmp) {
            args = strchr(tmp, ':');
            *args = '\0';
            args++;
            svc = service_find_by_name(tmp);
        }
    }
    if (svc) {
        service_start(svc, args); 启动服务
    } else {
        ERROR("no such service '%s'\n", name);
    }
    if (tmp)
        free(tmp);
}
流程图:
 
                     
                     
                        
                        