实现 Virtual A/B - 补丁

挑选以下补丁以解决以下已知问题。

在侧加载时正确检查可分配空间

在 Virtual A/B 设备上侧加载完整的 OTA 软件包时,如果该设备具有的超级分区大小小于“*2 * sum(更新组的大小)*”,则可能会失败,并且恢复日志 /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、重新构建,并刷写启动分区;如果设备不使用恢复分区作为启动分区,则刷写恢复分区。

修复合并期间的段错误

在应用 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()。这会启动合并过程。但是,设备会重启到旧的 slot。由于合并已开始,因此设备无法启动并变得无法操作。

将以下更改添加到您的源代码树。请注意,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 合并它们,则 Virtual A/B 配置可能会在合并过程中被错误地删除。要验证 Virtual A/B 配置在合并的目标文件中是否正确,请应用以下补丁:CL 2084183(合并动态分区信息中相同的键/值对)

更新必要的组件

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