实现虚拟 A/B - 补丁

择优挑选下列补丁程序可解决对应的已知问题。

旁加载时正确检查可分配的空间

在 super 分区小于“2 * 各个更新组大小的总和”的虚拟 A/B 设备上,旁加载完整 OTA 软件包的操作可能会失败,并且恢复日志 /tmp/recovery.log 中会显示下列内容:

The maximum size of all groups with suffix _b (...) has exceeded half of allocatable space for dynamic partitions ...

以下是一个日志示例:

[INFO:dynamic_partition_control_android.cc(1020)] Will overwrite existing partitions. Slot A may be unbootable until update finishes!
[...]
[ERROR:dynamic_partition_control_android.cc(803)] The maximum size of all groups with suffix _b (2147483648) has exceeded half of allocatable space for dynamic partitions 1073741824.

如果您遇到此问题,请择优挑选 CL 1399393,重新构建并刷写 boot 分区或 recovery 分区(如果设备不将 recovery 分区用作 boot 分区的话)。

修复了合并期间的分段错误

应用 OTA 更新后,在 VAB 合并过程中,调用 update_engine_client --cancel 会导致 CleanupPreviousUpdateAction 崩溃。如果 markSlotSuccessful 延迟出现,说明还可能会存在野指针错误。

这个问题通过添加 StopActionInternal 函数得到了解决。CleanupPreviousUpdateAction 会在销毁时取消待处理任务,其维护着一个用于跟踪消息循环中待处理任务的任务 ID 的变量。销毁时,待处理任务会被取消,以避免分段错误。

确保对 Android 11 源代码树进行以下更改,以修复合并过程中 update_engine 内出现的 SIGSEGV 崩溃问题:

  • CL 1439792(CL 1439372 的先决条件)
  • CL 1439372CleanupPreviousUpdateAction:在销毁时取消待处理任务)
  • CL 1663460(解决了 markSlotSuccessful 延迟出现时可能存在的野指针错误)

防止 update_engine 提前合并

设备启动(Android 11 及更高版本)并且启动完成后,update_engine 会调用 ScheduleWaitMarkBootSuccessful()WaitForMergeOrSchedule()。这会启动合并流程。不过,设备会重新启动,并恢复到原来的槽位。但由于合并已经开始,设备将无法启动,进而无法操作。

将以下更改添加到源代码树中。请注意,CL 1664859 是可选的。

  • CL 1439792(CL 1439372 的先决条件)
  • CL 1439372CleanupPreviousUpdateAction:在销毁时取消待处理任务)
  • CL 1663460(解决了 markSlotSuccessful 延迟出现时可能存在的野指针错误)
  • CL 1664859(可选 - 为 CleanupPreviousUpdateAction 添加 unittest

确保 dm-verity 配置正确无误

在 Android 11 及更高版本中,您可能会无意中使用以下 dm-verity 选项配置设备:

  • 内核中的 CONFIG_DM_VERITY_AVB=y
  • 配置为使用任意 verity 模式(例如 AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE),而未配置 AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO 的引导加载程序。

采用这种设备配置时,任何 verity 错误都会导致 vbmeta 分区损坏,并使非 A/B 设备变得无法操作。同样,如果合并已经开始,A/B 设备也可能会变得无法操作。请仅使用 AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO verity 模式。

  1. 在内核中设置 CONFIG_DM_VERITY_AVB=n
  2. 请改为将设备配置为使用 AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO 模式。

如需了解更多信息,请参阅以下 verity 文档:处理 dm-verity 错误

确认已正确配置合并后的文件

如果您分别构建系统映像和供应商映像,然后使用 merge_target_files 将两者合并,虚拟 A/B 配置可能会在合并过程中被错误地丢弃。如需验证合并后的目标文件中虚拟 A/B 配置是否正确,请应用以下补丁:CL 2084183(在动态分区信息中合并相同的键/值对)

更新必要组件

从 Android 13 开始,snapuserd 已从供应商 ramdisk 移至通用 ramdisk。如果您的设备即将升级到 Android 13,供应商 ramdisk 和通用 ramdisk 都可能包含 snapuserd 的副本。在这种情况下,虚拟 A/B 需要 snapuserd 的系统副本。为了确保正确的 snapuserd 副本已准备就绪,请应用 CL 2031243(将 snapuserd 复制到 first_stage_ramdisk)。