系统启动流程分析之system_server进程启动流程分析

「这是我参与2022首次更文挑战的第18天,活动详情查看:2022首次更文挑战」。

回顾

在前篇zygote进程启动流程分析中分析,

  1. 系统启动时,通过解析zygote的配置文件,生成zygote的服务Service,
  2. 然后通过Service的Start函数来启动这个Service,同时fork一个zygote进程,并最终会在init进程中启动app_process应用程序
  3. 在app_process应用程序的main函数中,会通过AppRuntime的start函数,初始化和启动一个Java虚拟机,并注册所有的JNI函数
  4. 同时会通过调用ZygoteInit.startSystemServer函数来fork一个system_server进程 今天,继续分析下这个system_server进程的启动流程

正文

在前篇中,分析道,在ZygoteInit.main函数中,通过如下代码fork了systemserver进程

zygoteServer = new ZygoteServer(isPrimaryZygote);
if (startSystemServer) {
    Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);

    // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
    // child (system_server) process.
    if (r != null) {
        r.run();
        return;
    }
}

可以看到,在这个函数中,首先初始化了一个Runnable,然后运行这个Runnable,因此

private static Runnable forkSystemServer(String abiList, String socketName,
            ZygoteServer zygoteServer) {
    // systemserver进程的功能性定义
    long capabilities = posixCapabilitiesAsBits(
            OsConstants.CAP_IPC_LOCK,
            OsConstants.CAP_KILL,
            OsConstants.CAP_NET_ADMIN,
            OsConstants.CAP_NET_BIND_SERVICE,
            OsConstants.CAP_NET_BROADCAST,
            OsConstants.CAP_NET_RAW,
            OsConstants.CAP_SYS_MODULE,
            OsConstants.CAP_SYS_NICE,
            OsConstants.CAP_SYS_PTRACE,
            OsConstants.CAP_SYS_TIME,
            OsConstants.CAP_SYS_TTY_CONFIG,
            OsConstants.CAP_WAKE_ALARM,
            OsConstants.CAP_BLOCK_SUSPEND
    );
    /* Containers run without some capabilities, so drop any caps that are not available. */
    StructCapUserHeader header = new StructCapUserHeader(
            OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
    StructCapUserData[] data;
    try {
        data = Os.capget(header);
    } catch (ErrnoException ex) {
        throw new RuntimeException("Failed to capget()", ex);
    }
    capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32);

    /* Hardcoded command line to start the system server */
    // 启动systemserver进程的一些必要性参数
    String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
                    + "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010,3011",
            "--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server",
            "--runtime-args",
            "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
            "com.android.server.SystemServer",
    };
    ZygoteArguments parsedArgs = null;

    int pid;

    try {
        // 对上述的参数进行解析,这个解析过程很简单,需要的话可以自行分析下
        parsedArgs = new ZygoteArguments(args);
        Zygote.applyDebuggerSystemProperty(parsedArgs);
        Zygote.applyInvokeWithSystemProperty(parsedArgs);

        if (Zygote.nativeSupportsTaggedPointers()) {
            /* Enable pointer tagging in the system server. Hardware support for this is present
             * in all ARMv8 CPUs. */
            parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_TBI;
        }

        /* Enable gwp-asan on the system server with a small probability. This is the same
         * policy as applied to native processes and system apps. */
        parsedArgs.mRuntimeFlags |= Zygote.GWP_ASAN_LEVEL_LOTTERY;

        if (shouldProfileSystemServer()) {
            parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
        }

        /* Request to fork the system server process */
        // 1. 调用Zygote的forkSystemServer函数
        pid = Zygote.forkSystemServer(
                parsedArgs.mUid, parsedArgs.mGid,
                parsedArgs.mGids,
                parsedArgs.mRuntimeFlags,
                null,
                parsedArgs.mPermittedCapabilities,
                parsedArgs.mEffectiveCapabilities);
    }
    // ...... catch exception异常捕获代码省略

    /* For child process */
    if (pid == 0) {
        if (hasSecondZygote(abiList)) {
            waitForSecondaryZygote(socketName);
        }

        zygoteServer.closeServerSocket();
        2. 调用函数处理system server进程的相关数据
        return handleSystemServerProcess(parsedArgs);
    }

    return null;
}

从这边看到,此处会调用Zygote的forkSystemServer函数来fork一个system_server进程,此后通过调用handleSystemServerProcess函数处理进程相关信息,因此

初始化system_server进程

static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
        int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
    ZygoteHooks.preFork();

    int pid = nativeForkSystemServer(
            uid, gid, gids, runtimeFlags, rlimits,
            permittedCapabilities, effectiveCapabilities);

    // Set the Java Language thread priority to the default value for new apps.
    Thread.currentThread().setPriority(Thread.NORM_PRIORITY);

    ZygoteHooks.postForkCommon();
    return pid;
}

private static native int nativeForkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
        int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);

如此,通过JNI函数调用的是Native层的nativeForkSystemServer函数,这个函数是在zygote进程被fork出来后,启动app_process应用程序后,在初始化和启动Java虚拟机的同时,通过startReg函数来注册的,以及将Java层函数和Native层函数进行关联的,因此

static jint com_android_internal_os_Zygote_nativeForkSystemServer(
        JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
        jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities,
        jlong effective_capabilities) {
    std::vector<int> fds_to_close(MakeUsapPipeReadFDVector()),
                   fds_to_ignore(fds_to_close);
    
    fds_to_close.push_back(gUsapPoolSocketFD);
    
    if (gUsapPoolEventFD != -1) {
        fds_to_close.push_back(gUsapPoolEventFD);
        fds_to_ignore.push_back(gUsapPoolEventFD);
    }
    
    if (gSystemServerSocketFd != -1) {
        fds_to_close.push_back(gSystemServerSocketFd);
        fds_to_ignore.push_back(gSystemServerSocketFd);
    }
    // 调用ForkCommon函数,在这个函数中fork一个进程,并返回其pid
    pid_t pid = ForkCommon(env, true, fds_to_close, fds_to_ignore, true);
    if (pid == 0) {
        // System server prcoess does not need data isolation so no need to
        // know pkg_data_info_list.
        SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
                       permitted_capabilities, effective_capabilities,
                       MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,
                       false, nullptr, nullptr, /* is_top_app= */ false,
                       /* pkg_data_info_list */ nullptr,
                       /* whitelisted_data_info_list */ nullptr, false, false);
    } else if (pid > 0) {
       // ......
    }
    return pid;
}

处理system_server进程的相关数据

private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
    // set umask to 0077 so new files and directories will default to owner-only permissions.
    Os.umask(S_IRWXG | S_IRWXO);

    // mNiceName是"system_server"
    if (parsedArgs.mNiceName != null) {
        Process.setArgV0(parsedArgs.mNiceName);
    }

    // ...... 功能无关代码省略

    if (parsedArgs.mInvokeWith != null) {
        // ...... 条件不满足代码省略
    } else {
        ClassLoader cl = null;
        if (systemServerClasspath != null) {
            cl = createPathClassLoader(systemServerClasspath, parsedArgs.mTargetSdkVersion);

            Thread.currentThread().setContextClassLoader(cl);
        }

        /*
         * Pass the remaining arguments to SystemServer.
         */
        // 最终会调用ZygoteInit的zygoteInit函数,初始化system_server进程
        // 此处需要注意的是,parsedArgs.mRemainingArgs是一个字符串数组,
        // 其包含的唯一元素为 "com.android.server.SystemServer"
        return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                parsedArgs.mDisabledCompatChanges,
                parsedArgs.mRemainingArgs, cl);
    }

    /* should never reach here */
}

此处parsedArgs是一个ZygoteArguments对象,在此前初始化的时候,分析该对象构造函数可知,此处的parsedArgs.mNiceName被设定为"system_server",同时parsedArgs.mRemainingArgs是一个字符串数组,其包含了唯一的元素"com.android.server.SystemServer" 然后调用的是ZygoteInit对象的zygoteInit函数

public static final Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
        String[] argv, ClassLoader classLoader) {
    // ...... 日志代码省略
    // 完成RuntimeInit对象的参数初始化
    RuntimeInit.commonInit();
    // 此处会调用ZygoteInit的nativeZygoteInit函数,从名字上来看,此函数应该是一个Native函数,
    // 最终会通过JNI调用到Native的nativeZygoteInit函数
    // 最后调用到AppRuntime的onZygoteInit函数,
    // 在这个函数中,会通过ProcessState对象的startThreadPool函数,启动线程池
    // 这个ProcessState此前有分析过,它是进程相关的,一个进程只有一个ProcessState指针对象
    // 调用其startThreadPool函数启动线程池
    ZygoteInit.nativeZygoteInit();
    // 最终通过RuntimeInit的applicationInit函数返回一个线程
    return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
            classLoader);
}

如上述代码注释所述,此处最终通过调用RuntimeInit的applicationInit函数来返回一个线程

protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
    // ......
    // 此前有说过,此处的argv只有一个元素"com.android.server.SystemServer"
    final Arguments args = new Arguments(argv);

    // ......

    // Remaining arguments are passed to the start class's static main
    // 调用findStaticMain函数,从名字看好像是查找static类型的main函数
    // 分析上述的Arguments对象,此处的args.startClass即为"com.android.server.SystemServer"
    // args.startArgs = null
    return findStaticMain(args.startClass, args.startArgs, classLoader);
}

protected static Runnable findStaticMain(String className, String[] argv,
            ClassLoader classLoader) {
    Class<?> cl;

    try {
        // 找到SystemServer类对象
        cl = Class.forName(className, true, classLoader);
    }
    // ...... catch exception 代码省略

    Method m;
    try {
        // 查找SystemServer.main函数
        m = cl.getMethod("main", new Class[] { String[].class });
    }
    // ...... catch exception 代码省略
    // 判断这个main函数是否为public static的,若非,则抛出异常
    int modifiers = m.getModifiers();
    if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
        throw new RuntimeException(
                "Main method is not public and static on " + className);
    }

    /*
     * This throw gets caught in ZygoteInit.main(), which responds
     * by invoking the exception's run() method. This arrangement
     * clears up all the stack frames that were required in setting
     * up the process.
     */
    // 返回一个MethodAndArgsCaller对象
    return new MethodAndArgsCaller(m, argv);
}

static class MethodAndArgsCaller implements Runnable {
    /** method to call */
    private final Method mMethod;

    /** argument array */
    private final String[] mArgs;
    // 设置函数和参数,其中此处的method为SystemServer.main函数对象,args为null
    public MethodAndArgsCaller(Method method, String[] args) {
        mMethod = method;
        mArgs = args;
    }
    // 这个类是一个Runnable对象,从上述的分析可知,在fork system_server进程后,会运行这个Runnable对象
    // 因此此处会继续调用这边的run函数,这样就直接运行起了SystemServer.main函数
    public void run() {
        try {
            mMethod.invoke(null, new Object[] { mArgs });
        }
        // ...... catch exception 代码省略
    }
}

如上备注所示,这边最终会调用了SystemServer.main函数,从而进入了SystemServer类,在这个类中会初始化系统所必须的很多服务,对象等,这些是后话

总结

如上的所有代码分析,可知zygote进程启动和system_server进程启动流程如下

  1. 系统启动过程中,会通过配置文件解析出zygote进程对应的Service服务
  2. 服务在启动的过程中,会fork一个进程zygote
  3. 在fork zygote进程后,启动了一个应用程序app_process
  4. 在app_process应用程序的main函数中,初始化了一个AppRuntime对象,这个对象继承自AndroidRuntime,然后调用这个对象的start函数
  5. 在AndroidRuntime::start函数中,调用startVm和onVmCreate函数来初始化一个Java虚拟机,如果分析这两个函数,我们会知道,这个JavaVM对象是进程相关的,一个进程只有一个JavaVM(Java虚拟机),同时在这个过程中,我们会看到一个我们非常熟悉的参数JNIEnv指针对象,在startVm函数调用时会初始化,当然此处我们不作过多分析,有兴趣的可以自行去追踪下代码
  6. 在AndroidRuntime::start函数中,会调用startReg函数注册很多JNI函数
  7. 在AndroidRuntime::start函数的最后调用ZygoteInit.main函数
  8. 在ZygoteInit.main函数中首先通过preload函数加载系统所需的很多类和资源等
  9. 此后调用forkSystemServer函数,这个函数会返回一个Runnable对象
  10. 在这个forkSystemServer函数中,通过Zygote.forkSystemServer函数fork一个system_server进程
  11. 又通过handleSystemServerProcess函数来通过ZygoteInit.zygoteInit函数,最终调用RuntimeInit.applicationInit函数获取一个MethodAndArgsCaller对象,这个MethodAndArgsCaller类继承自Runnable
  12. 最终,在ZygoteInit.forkSystemServer函数中运行上述的MethodAndArgsCaller对象,从而调用了SystemServer的main函数

综上,如下为此流程的函数调用时序图 图片.png