软重启(<= AOSP 14)

Android 11 支持软重启,它是用户空间中进程的运行时重启,用于应用需要重启的更新(例如,APEX 软件包的更新)。目前,软重启仅限于在 userdata 挂载后启动的进程。

可通过以下方式请求软重启

  • PowerManager,通过调用 PowerManager.reboot(PowerManager.REBOOT_USERSPACE)

  • 从 Shell,使用 adb shell svc power reboot userspaceadb reboot userspace

软重启后,凭据加密存储保持解锁状态。

如果设备支持软重启,则 PowerManager.isRebootingUserspace() API 方法会返回 true,并且系统属性 init.userspace_reboot.is_supported 的值等于 1

如果设备不支持软重启,则调用 PowerManager.reboot(PowerManager.REBOOT_USERSPACE)adb reboot userspaceadb shell svc power reboot userspace 将会失败。

软重启执行

在请求软重启后(通过 PowerManager 或从 shell),init 执行以下步骤

  1. 接收 sys.powerctl=reboot,userspace

  2. fork 一个单独的 UserspaceRebootWatchdogThread() 进程来监控软重启。

  3. 触发 userspace-reboot-requested 操作,该操作会重置所有可能影响软重启的系统属性。受影响的属性

    • sys.usb.config
    • sys.usb.state
    • sys.boot_completed
    • dev.bootcomplete
    • sys.init.updatable_crashing
    • sys.init.updatable_crashing_process_name
    • apexd.status
    • sys.user.0.ce_available
    • sys.shutdown.requested
    • service.bootanim.exit

    上述属性应在启动序列期间再次设置。如果需要,您可以重置其他属性。例如,请参阅 rootdir/init.rc 中的 on userspace-reboot-requested 操作。

  4. 运行 DoUserspaceReboot 函数,该函数执行以下操作

    1. 向在挂载 userdata 后启动的进程发送 SIGTERM,并等待它们停止。
    2. 达到超时后,发送 SIGKILL 以杀死任何正在运行的进程。
    3. 调用 /system/bin/vdc volume reset
    4. 卸载 zRAM 后备设备。
    5. 卸载活动的 APEX 软件包。
    6. 切换回引导程序挂载命名空间。
    7. 触发 userspace-reboot-resume 操作。

如果在软重启之前请求了文件系统检查点,则在 userspace-reboot-fs-remount 操作期间,userdata 将重新挂载到检查点模式(有关详细信息,请参见以下部分)。在 sys.boot_completed property 设置为 1 后,即认为软重启已完成。在软重启结束时,显示屏将保持关闭状态,并且需要显式的用户交互才能唤醒它。

文件系统检查点

如果在软重启之前请求了文件系统检查点,则在软重启期间,userdata 将重新挂载到检查点模式。重新挂载逻辑在 fs_mgr_remount_userdata_into_checkpointing 函数中实现,并且因检查点方法而异。具体而言,当 userdata 支持时

  • 文件系统级检查点(例如,f2fs),userdata 将使用 checkpoint=disable 选项重新挂载。

  • 块级检查点(例如,ext4),然后卸载 /data,并销毁其挂载的所有父设备映射器设备。接下来,userdata 将使用与正常检查点启动中使用的相同代码路径进行挂载。

如果文件系统级密钥环用于管理凭据加密 (CE) 和设备加密 (DE) 密钥,则在卸载 userdata 后,密钥将丢失。为了允许密钥恢复,在将密钥安装到文件系统密钥环时,vold 还会将类型为 fscrypt-provisioning 的相同密钥安装到会话级密钥环。当调用 init_user0 时,vold 会在文件系统密钥环中重新安装密钥。

回退到硬重启

为了确保软重启不会使设备处于无法使用的状态,Android 11 包含回退到硬重启的机制,当满足以下条件之一时会触发该机制

  • 设备在给定的超时时间内未能启动软重启(即,sys.init.userspace_reboot.in_progress=1)。
  • 进程在给定的超时时间内未能停止。
  • /system/bin/vdc volume reset 操作失败。
  • zRAM 设备的卸载失败。
  • 活动的 APEX 软件包卸载不正确。
  • 尝试将 userdata 重新挂载到检查点模式失败。
  • 设备在给定的超时时间内未能成功启动(即,sys.boot_completed=1)。

按设备配置

可以通过更改以下属性的值来调整某些软重启方面

  • init.userspace_reboot.is_supported 控制设备何时可以执行软重启。如果此属性的值为 false0 或未指定,则尝试重启将被拒绝。
  • init.userspace_reboot.sigkill.timeoutmillis 控制进程接收到 SIGKILL 信号后停止的超时时间(以毫秒为单位)。如果其中一个进程在给定的超时时间内未能停止,则会触发回退到硬重启。
  • init.userspace_reboot.sigterm.timeoutmillis 控制进程接收到 SIGTERM 信号后终止的超时时间(以毫秒为单位)。所有在给定的超时时间内未能终止的进程都将收到 SIGKILL 信号。
  • init.userspace_reboot.started.timeoutmillis 控制软重启启动的超时时间(以毫秒为单位)(即,sys.init.userspace_reboot.in_progress=1)。如果设备在给定的超时时间内未能启动软重启,则会触发回退到硬重启。
  • init.userspace_reboot.userdata_remount.timeoutmillis 控制卸载 userdata 的超时时间(以毫秒为单位)。如果设备在给定的超时时间内未能卸载 userdata,则会触发回退到硬重启。
  • init.userspace_reboot.watchdog.timeoutmillis 控制设备成功启动的超时时间(以毫秒为单位)(即,sys.boot_completed=1)。如果设备在给定的超时时间内未能启动,则会触发回退到硬重启。

自定义软重启期间的动画

软重启的参考实现包括自定义软重启期间显示的动画的功能。

userspace-reboot-fs-remount 操作结束时,init 启动 bootanim 服务。此服务按列出的顺序查找以下动画文件是否存在,并播放找到的第一个文件

  • /product/media/userspace-reboot.zip
  • /oem/media/userspace-reboot.zip
  • /system/media/userspace-reboot.zip

如果未指定任何特定于软重启的动画文件,则 bootanim 将显示默认的 android 动画。

测试

Android 11 包括软重启的参考实现。此外,您可以使用 UserspaceRebootHostTest 中的 CTS 测试来验证软重启。