forkSystemServer
forkSystemServer() 不是对通用应用 fork 的简单包装。它在 Java 中构造固定的 system uid/gid、supplementary groups、capability 和目标类参数,再根据设备能力补充 MTE、GWP-ASan 与 profile flags,最后调用专用 native fork。父 Zygote 得到子 pid 并返回 null;子进程得到 0,等待 secondary Zygote、关闭继承 socket,再把 parsedArgs 交给 handleSystemServerProcess()。
1. Capability候选集
源码文件:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
long capabilities =
(1L << OsConstants.CAP_IPC_LOCK) |
(1L << OsConstants.CAP_KILL) |
(1L << OsConstants.CAP_NET_ADMIN) |
(1L << OsConstants.CAP_NET_BIND_SERVICE) |
(1L << OsConstants.CAP_NET_BROADCAST) |
(1L << OsConstants.CAP_NET_RAW) |
(1L << OsConstants.CAP_SYS_NICE) |
(1L << OsConstants.CAP_SYS_PTRACE) |
(1L << OsConstants.CAP_SYS_TIME) |
(1L << OsConstants.CAP_SYS_TTY_CONFIG) |
(1L << OsConstants.CAP_WAKE_ALARM) |
(1L << OsConstants.CAP_BLOCK_SUSPEND) |
(1L << OsConstants.CAP_MAC_ADMIN);这是期望集合,不是无条件最终集合。SystemServer 需要网络管理、进程终止、调度、唤醒和 safesetid policy 等能力;每个 bit 的消费者属于后续具体系统服务。forkSystemServer() 只负责把候选集合传给 specialization。
2. 与当前能力取交集
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 &= Integer.toUnsignedLong(data[0].effective)
| (Integer.toUnsignedLong(data[1].effective) << 32);Zygote 用 capget() 读取自身 effective set,再与候选集合取交集。容器或裁剪环境缺少的 capability 不会凭 SystemServer 参数重新产生。capget 失败会阻止 fork;这比在子进程中带着未知 capability 状态继续启动更安全。
3. 固定参数协议
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,3005,3006,3007,3009,3010,3011,3012",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
"com.android.server.SystemServer",
};这些参数复用 ZygoteArguments 协议:uid/gid 切到 system,groups 提供设备/网络等 supplementary 权限,permitted/effective capability 使用同一交集结果,目标类固定为 SystemServer。参数先写入内存 ZygoteCommandBuffer 再由统一 parser 解析,避免 SystemServer 特殊路径和普通 Zygote 命令对字段语义产生两套实现。
4. Runtime flags
源码文件:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
Zygote.applyDebuggerSystemProperty(parsedArgs);
Zygote.applyInvokeWithSystemProperty(parsedArgs);
if (Zygote.nativeSupportsMemoryTagging()) {
String mode = SystemProperties.get(
"persist.arm64.memtag.system_server", "");
if (mode.isEmpty()) {
mode = SystemProperties.get(
"persist.arm64.memtag.default", "async");
}
if (mode.equals("async")) {
parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_ASYNC;
} else if (mode.equals("sync")) {
parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_SYNC;
} else if (!mode.equals("off")) {
parsedArgs.mRuntimeFlags |= Zygote.nativeCurrentTaggingLevel();
}
} else if (Zygote.nativeSupportsTaggedPointers()) {
parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_TBI;
}
parsedArgs.mRuntimeFlags |= Zygote.GWP_ASAN_LEVEL_LOTTERY;
if (shouldProfileSystemServer()) {
parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
}MTE 分支首先看硬件/runtime 支持,再读 SystemServer 专用属性;非法 mode 保留当前 tagging level 并记录错误。没有 MTE 但支持 tagged pointers 时使用 TBI。GWP-ASan lottery 无条件加入 runtime flags,profile 则受实验属性控制。这些 flags 在 native specialization/post-fork 中消费,不是 SystemServer.main() 自己解析。
5. Native fork入口
pid = Zygote.forkSystemServer(
parsedArgs.mUid,
parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);SystemServer 使用专用 Zygote.forkSystemServer(),rlimits 参数传 null。native 层负责真正 fork、uid/gid/groups、capability、SELinux、seccomp 和 post-fork hooks。Java 返回值仍遵循 POSIX 语义:父进程为 child pid,子进程为 0,错误通过异常/abort 路径处理。
6. 子进程同步与交接
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
return null;双 Zygote 配置下,SystemServer 子进程等待另一 socket 可连接,保证后续 32/64 位应用路由的基础服务已就绪。然后关闭继承的监听 socket,避免 SystemServer 持有 Zygote 控制 fd。返回的 Runnable 才是下一阶段入口;父 Zygote得到 null 并继续 runSelectLoop()。
7. 失败与owner
capget失败:Zygote Java 阶段终止,尚未 fork;- 参数 parser 失败:包装为 RuntimeException,不进入 native fork;
- MTE 属性非法:记录错误并保留当前 tagging level,不直接停止;
- native fork/specialization 失败:由 native Zygote 路径终止或抛错;
- secondary Zygote 长时间不可连接:SystemServer 子进程阻塞在连接等待,尚未进入
handleSystemServerProcess(); - socket close 失败:记录清理错误,必须结合子进程是否仍持有监听 fd 判断风险。
8. 导航与后续
# 输入 SystemServer fork 实现,输出 capability、参数、runtime flags 和父子分支。
rg -n "forkSystemServer|capget|--setuid=1000|MEMORY_TAG|GWP_ASAN|PROFILE_SYSTEM_SERVER|waitForSecondaryZygote" \
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
# 输入 native Zygote,输出专用 fork 与 specialization 消费者。
rg -n "nativeForkSystemServer|forkSystemServer|SpecializeCommon|postForkSystemServer" \
frameworks/base/core/java/com/android/internal/os/Zygote.java \
frameworks/base/core/jni/com_android_internal_os_Zygote.cpp下一篇将展开 handleSystemServerProcess():umask、进程名、classloader、profile、invoke-with 和 zygoteInit() 交接;不会重复本文的 capability 与 native fork 输入。
