Skip to content

守护进程关系

追踪 init 启动 servicemanager、surfaceflinger、zygote 与 system_server 的入口、就绪点和重启边界。

基于android-17.0.0_r1
Androidinitservicemanagersurfaceflingerzygotesystem_server

守护进程关系 ​

本文面向已经读过 启动阶段 和 Init主循环 的读者。前文把 rc 事件当作队列中的 action;本文继续沿着 Android 启动源码回答一个容易混淆的问题:start 命令返回后,servicemanager、surfaceflinger、zygote 和 system_server 分别在什么时候才具有自己的“可用”含义?

这里的“可用”不是一个统一状态。init 只拥有服务进程的创建和回收状态;Binder 服务由 native 进程发布;system_server 的服务由 Java 框架分阶段注册。本文不展开 Binder 驱动协议、SurfaceFlinger 合成算法或 SystemServer 各项服务的内部实现,而是给出从 rc 到消费者的入口地图、失败边界和可执行验证方法。

1. 依赖边界 ​

1.1 四个对象 ​

对象进程所有者init 的职责外部消费者
servicemanagernative 独立进程fork/exec、uid、class、重启defaultServiceManager() 和 Binder 客户端
surfaceflingernative 独立进程fork/exec、图形组、重启 zygote 的条件动作SurfaceFlinger Binder 接口、显示栈
zygotenative app_process64 进入 Java创建进程、预加载、监听 zygote socketframework 启动器和应用进程请求
system_serverzygote fork 的 Java 子进程没有独立 init service 定义SystemServiceManager 和各 Java 服务消费者

system_server 不在任何 service ... rc 条目中。init.zygote64.rc 的 --start-system-server 只是传给 app_process64 的参数;真正的 fork 发生在 ZygoteInit.forkSystemServer()。

1.2 三个时刻 ​

同一个服务至少有三个可观察时刻:

  1. Service::Start() 创建并执行目标进程,init 可把 init.svc.<name> 推进到 running。
  2. 进程完成自己的初始化并向 servicemanager 发布 Binder 对象,客户端查找才可能成功。
  3. 更高层的消费者完成握手或 boot phase;这一步可能由 Java 服务注册、属性或专用协议定义。

因此 init.svc.surfaceflinger=running 不能推出 SurfaceFlinger 已经能被 Binder 查到;同理 zygote 的 running 也不能推出 system_server 已完成 startOtherServices()。

2. 类启动 ​

2.1 入口 ​

Android 17 的 /system/core/rootdir/init.rc 将入口分开:on zygote-start 直接启动两个 zygote;on boot 启动 hal 和 core class;on nonencrypted 才启动 main 和 late_start class。

源码文件:system/core/rootdir/init.rc

text
on zygote-start
    wait_for_prop odsign.verification.done 1
    start statsd
    start zygote
    start zygote_secondary

on boot
    class_start hal
    class_start core

on nonencrypted
    class_start main
    class_start late_start

class main 是 zygote 的属性,但首次启动并不依赖 class_start main;zygote 由显式 start zygote 触发。nonencrypted 是挂载流程产生的历史事件名,是否到达它取决于当前加密和 fs_mgr 路径。

2.2 条件 ​

do_class_start() 先读取 persist.init.dont_start_class.<class>,再遍历 ServiceList。显式 disabled 服务不会被 class 启动,必须使用单独的 start。

源码文件:system/core/init/builtins.cpp

cpp
static Result<void> do_class_start(const BuiltinArguments& args) {
    if (android::base::GetBoolProperty(
            "persist.init.dont_start_class." + args[1], false)) {
        return {};
    }
    for (const auto& service : ServiceList::GetInstance()) {
        if (service->classnames().count(args[1])) {
            if (auto result = service->StartIfNotDisabled(); !result.ok()) {
                LOG(ERROR) << "Could not start service '" << service->name()
                           << "' as part of class '" << args[1]
                           << "': " << result.error();
            }
        }
    }
    return {};
}

这个循环的所有者是 ServiceList,不是 rc 文件。属性开关会让整个 class 静默跳过;单个服务启动失败只记录错误并继续遍历,因此不能把 class_start core 当成全有或全无的事务。

2.3 失败 ​

class_restart --only-enabled main 使用同一个属性 gate,并额外跳过 IsEnabled() 为假的服务。servicemanager 的 rc 恰好使用这种形式;它重启的是当前启用的 main、hal、early_hal 服务,而不是一份手写的依赖清单。

源码文件:system/core/init/builtins.cpp

cpp
bool only_enabled = false;
if (args.size() == 3) {
    if (args[1] != "--only-enabled") return Error() << "Unexpected argument";
    only_enabled = true;
    classname = args[2];
}
for (const auto& service : ServiceList::GetInstance()) {
    if (service->classnames().count(classname) &&
        (!only_enabled || service->IsEnabled())) {
        service->Restart();
    }
}

3. 名称服务 ​

3.1 rc入口 ​

frameworks/native/cmds/servicemanager/servicemanager.rc 定义了一个 core animation 服务,运行身份是 system,并标记为 critical。这些字段由 init 在 Service::Start() 前应用;它们不代表 Binder 注册已经发生。

源码文件:frameworks/native/cmds/servicemanager/servicemanager.rc

text
service servicemanager /system/bin/servicemanager
    class core animation
    user system
    group system readproc
    critical
    file /dev/kmsg w
    onrestart setprop servicemanager.ready false
    onrestart restart --only-if-running apexd
    onrestart restart audioserver
    onrestart restart gatekeeperd
    onrestart class_restart --only-enabled main
    onrestart class_restart --only-enabled hal
    onrestart class_restart --only-enabled early_hal
    shutdown critical

3.2 注册点 ​

native main() 首先选择 Binder 驱动并建立 ProcessState,然后把自己的 ServiceManager 注册为名为 manager 的服务,再成为 context manager。

源码文件:frameworks/native/cmds/servicemanager/main.cpp

cpp
sp<ProcessState> ps = ProcessState::initWithDriver(driver);
ps->setThreadPoolMaxThreadCount(0);
sp<ServiceManager> manager = sp<ServiceManager>::make(std::make_unique<Access>());
manager->addService("manager", manager, false, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT);
IPCThreadState::self()->setTheContextObject(manager);
if (!ps->becomeContextManager()) {
    LOG(FATAL) << "Could not become context manager";
}

这里的消费者是 Binder 驱动和后续 defaultServiceManager() 调用者。becomeContextManager() 失败会使进程 fatal,因而不会进入正常循环。

3.3 就绪点 ​

servicemanager 建立 Looper、注册 Binder fd 后才设置 servicemanager.ready=true,随后永久 pollAll(-1)。这个属性是一个明确的生效点,但它只证明名称服务已进入事件循环,不证明任何具体业务服务都已注册。

源码文件:frameworks/native/cmds/servicemanager/main.cpp

cpp
sp<Looper> looper = Looper::prepare(false);
sp<BinderCallback> binderCallback = BinderCallback::setupTo(looper);
ClientCallbackCallback::setupTo(looper, manager, binderCallback);
if (!SetProperty("servicemanager.ready", "true")) {
    LOG(ERROR) << "Failed to set servicemanager ready property";
}
while (true) {
    looper->pollAll(-1);
}

若进程在设置属性前退出,init 可能仍短暂显示启动过;若属性为 true 但某服务查不到,应转向该服务自己的 addService 调用和权限检查,而不是重复检查 class 顺序。

4. 图形服务 ​

4.1 rc入口 ​

surfaceflinger 也属于 core animation,但其重启动作带有 --only-if-running:只有 zygote 当时已经运行,才向 init 请求重启 zygote。

源码文件:frameworks/native/services/surfaceflinger/surfaceflinger.rc

text
service surfaceflinger /system/bin/surfaceflinger
    class core animation
    user system
    group graphics drmrpc readproc
    capabilities SYS_NICE
    onrestart restart --only-if-running zygote
    task_profiles HighPerformance

这是一条失败方向的边界:surfaceflinger 崩溃不会无条件拉起一个从未运行过的 zygote。

4.2 初始化 ​

main_surfaceflinger.cpp 的入口先配置 RPC、Binder 线程池和图形 allocator,再创建并初始化 SurfaceFlinger。这些步骤属于 surfaceflinger 自己的 owner,init 不会替它完成。

源码文件:frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp

cpp
signal(SIGPIPE, SIG_IGN);
hardware::configureRpcThreadpool(1, false);
startGraphicsAllocatorService();
ProcessState::self()->setThreadPoolMaxThreadCount(4);
ProcessState::self()->startThreadPool();
sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();
flinger->init();

4.3 发布点 ​

初始化完成后,surfaceflinger 才向 servicemanager 发布两个 Binder 名称,最后进入自己的运行循环。读者可以用这三个点区分“进程存在”“服务可查”“线程开始处理事务”。

源码文件:frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp

cpp
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);
sp<SurfaceComposerAIDL> composerAIDL = sp<SurfaceComposerAIDL>::make(flinger);
sm->addService(String16("SurfaceFlingerAIDL"), composerAIDL, false);
flinger->run();

5. Zygote ​

5.1 参数 ​

init.zygote64.rc 的命令行同时决定 native 可执行文件、zygote socket 和是否创建 system_server:

源码文件:system/core/rootdir/init.zygote64.rc

text
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
    class main
    priority -20
    user root
    group root readproc reserved_disk
    socket zygote stream 660 root system
    socket usap_pool_primary stream 660 root system
    critical window=${zygote.critical_window.minute:-off} target=zygote-fatal

init 在 Service::Start() 阶段创建 socket,并通过环境变量交给 app_process64。Java 侧 ZygoteInit.main() 解析 start-system-server、socket 名称和 ABI;没有 ABI 参数会直接抛出异常。

5.2 分叉 ​

解析参数、预加载和 native 状态初始化完成后,ZygoteInit 调用 forkSystemServer()。该函数构造 uid 1000、gid 1000、capabilities、nice name 和 com.android.server.SystemServer 参数,调用 native Zygote.forkSystemServer()。

源码文件:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

java
if (startSystemServer) {
    Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
    if (r != null) {
        r.run();
        return;
    }
}
Log.i(TAG, "Accepting command socket connections");
caller = zygoteServer.runSelectLoop(abiList);

父进程中的返回值为 null,继续监听 zygote socket;子进程得到 Runnable,关闭 zygote server socket 后进入 system_server 入口。这是“zygote 运行”与“system_server 已生成”的进程边界。

5.3 循环 ​

zygote 的正常结束路径不是退出,而是 runSelectLoop() 持续等待 fork 请求。若预加载或参数解析抛出异常,main() 记录 System zygote died with fatal exception 后结束;随后 rc 中的 critical 和 onrestart 才由 init 接管恢复策略。二次 zygote 的 rc 还声明 onrestart restart zygote,因此不能把两个 zygote 的重启关系混为一谈。

6. 系统服务 ​

6.1 子进程 ​

SystemServer.java 的 main() 只是 new SystemServer().run()。run() 在 Java 主线程准备 Looper 和 init thread pool 后,按 bootstrap、core、other、APEX 四组启动服务。

源码文件:frameworks/base/services/java/com/android/server/SystemServer.java

java
public static void main(String[] args) {
    new SystemServer().run();
}

startBootstrapServices(t);
startCoreServices(t);
startOtherServices(t);
startApexServices(t);

这些组不是 init class。它们由 SystemServiceManager 和 framework boot phase 拥有,服务注册和依赖检查发生在同一个 Java 子进程内部。

6.2 生效点 ​

SystemServer 的“ready”至少有三层含义:某个 Java 服务已由 SystemServiceManager 创建;它在对应 boot phase 发布 Binder;SystemServer 完成启动组并记录 SYSTEM_SERVER_READY。最后才进入主 Looper。

源码文件:frameworks/base/services/java/com/android/server/SystemServer.java

java
FrameworkStatsLog.write(
        FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
        SYSTEM_SERVER_READY, uptimeMillis);
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");

init.svc.system_server 不是可靠查询项,因为 system_server 没有 rc service 名称。诊断应使用 ps、zygote 日志、framework service 查询和对应的 Binder 注册点组合判断。

6.3 失败路径 ​

启动四组服务的 try 块捕获任意 Throwable,记录 Failure starting system services 后重新抛出。这里没有“只跳过一个失败服务然后继续”的通用保证;具体服务可能有自己的降级分支,但 SystemServer 总体启动失败会结束子进程,恢复责任回到 zygote/init 的更外层。

7. 重启链 ​

7.1 所有者 ​

服务退出后,init 的 Service 对象负责状态、退出码和 restart policy;rc 的 onrestart action 负责副作用;被重启的服务负责重新建立自己的 Binder 或 socket 发布。三者不能互相替代。

7.2 条件重启 ​

servicemanager 的 onrestart restart --only-if-running apexd 和 surfaceflinger 的同名选项都会先检查目标服务是否已启用并处于运行相关状态;条件不满足时 action 成功但不创建新进程。其余 restart audioserver 等是明确列出的服务动作,不是隐含的全图重启。

7.3 临界点 ​

critical 由 init 统计崩溃窗口并决定是否触发更严重的系统恢复;onrestart 只在该服务进入重启处理时执行。zygote 的 critical window=... target=zygote-fatal 与 servicemanager 的 critical 参数形式不同,必须回到各自 rc 和 Service 实现判断,不能从“都是 critical”推出相同阈值。

8. 守护进程验证 ​

8.1 入口映射 ​

可以按下面的顺序复述整条主线:

text
rootdir/init.rc:on zygote-start
  -> init Service::Start
  -> init.zygote64.rc /system/bin/app_process64
  -> ZygoteInit.main
  -> forkSystemServer
  -> SystemServer.main/run
  -> startBootstrapServices ... Looper.loop

servicemanager 和 surfaceflinger 走另一条 native 支线:

text
servicemanager.rc / surfaceflinger.rc
  -> native main
  -> Binder 初始化
  -> addService(若有)
  -> Looper 或 flinger->run

8.2 设备查询 ​

在 userdebug/eng 设备上,可以把三个层次分别查询,而不是只看一个属性:

bash
adb shell getprop init.svc.servicemanager
adb shell getprop servicemanager.ready
adb shell service list | grep -E 'SurfaceFlinger|manager'
adb shell ps -A -o PID,PPID,NAME,STATE | grep -E 'zygote|system_server|surfaceflinger'
adb shell logcat -b all -d -s Zygote SystemServer SurfaceFlinger servicemanager

这些命令能证明进程状态、名称服务属性、Binder 列表和日志是否一致;不能证明每个 framework 服务的业务请求已经可用,也不能替代特定设备的 SELinux、HAL 和 overlay 检查。

8.3 故障定位 ​

若看到 init.svc.surfaceflinger=running 但 service list 找不到 SurfaceFlinger,先检查 main_surfaceflinger.cpp 的 addService 返回路径和 servicemanager 是否 ready;若 zygote 正常而没有 system_server,检查 ZygoteInit 的 forkSystemServer 异常和子进程日志;若 servicemanager 重启,沿其 rc 的 onrestart 逐条确认哪些消费者被重新拉起。

读者可以任选一个现象,写出“入口 → owner → 状态变化 → consumer → 生效点”的五段链路,并用上述命令验证。验证结果只覆盖固定版本和当前设备配置,不外推到厂商 rc、recovery 或 Microdroid 的完整启动图。