Android 11 支持软重启,即在运行时重启用户空间中的进程,以便应用要求重新启动的更新(例如对 APEX 软件包的更新)。目前,软重启仅适用于在 userdata
装载后启动的进程。
您可以采用以下方式请求软重启:
通过
PowerManager
调用PowerManager.reboot(PowerManager.REBOOT_USERSPACE)
从 shell 中使用
adb shell svc power reboot userspace
或adb reboot userspace
命令
软重启后,凭据加密存储空间仍保持解锁状态。
如果设备支持软重启,那么 PowerManager.isRebootingUserspace()
API 方法会返回 true
,系统属性 init.userspace_reboot.is_supported
的值则等于 1
。
如果设备不支持软重启,那么对 PowerManager.reboot(PowerManager.REBOOT_USERSPACE)
、adb reboot
userspace
和 adb shell svc power reboot userspace
的调用会失败。
软重启的执行
通过 PowerManager
或从 shell 中请求软重启后,init
会执行以下步骤:
接收
sys.powerctl=reboot,userspace
。复刻一个单独的
UserspaceRebootWatchdogThread()
进程来监控软重启。触发
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
操作。运行
DoUserspaceReboot
函数,该函数会执行以下操作:- 将
SIGTERM
发送到在userdata
装载后启动的进程,并等待这些进程停止。 - 达到超时时间后,发送
SIGKILL
以终止任何还在运行的进程。 - 调用
/system/bin/vdc volume reset
。 - 卸载 zRAM 后备设备。
- 卸载处于活动状态的 APEX 软件包。
- 切换回引导装载命名空间。
- 触发
userspace-reboot-resume
操作。
- 将
如果在软重启之前请求了创建文件系统检查点,userspace-reboot-fs-remount
操作执行期间会将 userdata
重新装载到检查点模式下(详见下一部分)。在 sys.boot_completed property
被设为 1
之后,即认为软重启完成。软重启结束时,屏幕会保持关闭状态,需要有明确的用户互动才能唤醒屏幕。
文件系统检查点的创建
如果在软重启之前请求了文件系统检查点,软重启期间会将 userdata
重新装载到检查点模式下。重新装载逻辑在 fs_mgr_remount_userdata_into_checkpointing
函数中实现,而且因检查点创建方法而异。具体而言,当 userdata
支持:
创建文件系统级检查点(例如
f2fs
)时,使用checkpoint=disable
选项重新装载userdata
。创建块级检查点(例如
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
用于控制设备何时可以执行软重启。如果此属性的值为false
、0
或未指定,尝试重启就会被拒绝。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 测试来验证软重启。