自 2025 年 3 月 27 日起,我们建议您使用 android-latest-release
而非 aosp-main
构建 AOSP 并为其做出贡献。如需了解详情,请参阅 AOSP 的变更。
实现虚拟 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
崩溃问题:
防止 update_engine 提前合并
设备启动(Android 11 及更高版本)并且启动完成后,update_engine
会调用 ScheduleWaitMarkBootSuccessful()
和 WaitForMergeOrSchedule()
。这会启动合并流程。不过,设备会重新启动,并恢复到原来的槽位。但由于合并已经开始,设备将无法启动,进而无法操作。
将以下更改添加到源代码树中。请注意,CL 1664859 是可选的。
确保 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 模式。
- 在内核中设置
CONFIG_DM_VERITY_AVB=n
。
- 请改为将设备配置为使用
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)。
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-03-26。
[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["没有我需要的信息","missingTheInformationINeed","thumb-down"],["太复杂/步骤太多","tooComplicatedTooManySteps","thumb-down"],["内容需要更新","outOfDate","thumb-down"],["翻译问题","translationIssue","thumb-down"],["示例/代码问题","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2025-03-26。"],[],[],null,["# Implement Virtual A/B - patches\n\nCherry-pick the following patches to address the following known issues.\n\n### Check allocatable space correctly when sideloading\n\nSideloading a full OTA package on a Virtual A/B device that has a super\npartition with a size smaller than \\*2 \\* sum(size of update groups)\\* may fail\nwith the following in recovery log `/tmp/recovery.log`: \n\n The maximum size of all groups with suffix _b (...) has exceeded half of allocatable space for dynamic partitions ...\n\nHere is an example of the log: \n\n [INFO:dynamic_partition_control_android.cc(1020)] Will overwrite existing partitions. Slot A may be unbootable until update finishes!\n [...]\n [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.\n\nIf you encounter this issue, cherry pick [CL\n1399393](https://android-review.googlesource.com/1399393), rebuild, and flash\nthe boot partition or recovery partition if the device doesn't use recovery as\nboot.\n\n### Fix segmentation fault during merge\n\nAfter applying an OTA update, during the VAB merge process, a call to\n`update_engine_client --cancel` causes `CleanupPreviousUpdateAction` to crash. A\npotential wild pointer error also exists when `markSlotSuccessful` comes late.\n\nThis was resolved by adding the `StopActionInternal` function.\n`CleanupPreviousUpdateAction` cancels pending tasks on destroy. It maintains a\nvariable that tracks the task ID of the pending task in the message loop. On\ndestroy, the pending task is canceled to avoid segfault.\n\nEnsure the following changes are in your Android 11 source tree to fix `SIGSEGV`\ncrashes in `update_engine` during merge:\n\n- [CL 1439792](https://android-review.googlesource.com/1439792) (a prerequisite to CL 1439372)\n- [CL 1439372](https://android-review.googlesource.com/1439372) (`CleanupPreviousUpdateAction`: cancel pending tasks on destroy)\n- [CL 1663460](https://android-review.googlesource.com/1663460) (fix the potential wild pointer error when `markSlotSuccessful` comes late)\n\n### Prevent update_engine premature merge\n\nWhen a device boots (Android 11 and higher), and the boot completes, the\n`update_engine` calls `ScheduleWaitMarkBootSuccessful()`, and\n`WaitForMergeOrSchedule()`. This starts the merge process. However, the device\nreboots to the old slot. Because the merge already started, the device fails to\nboot and becomes inoperable.\n\nAdd the following changes to your source tree. Note that CL 1664859 is optional.\n\n- [CL 1439792](https://android-review.googlesource.com/1439792) (a prerequisite to CL 1439372)\n- [CL 1439372](https://android-review.googlesource.com/1439372) (`CleanupPreviousUpdateAction`: cancel pending tasks on destroy)\n- [CL 1663460](https://android-review.googlesource.com/1663460) (fix the potential wild pointer error when `markSlotSuccessful` comes late)\n- [CL 1664859](https://android-review.googlesource.com/1664859) (optional - add `unittest` for `CleanupPreviousUpdateAction`)\n\n### Ensure the correct dm-verity configuration\n\nIn Android 11 and higher, devices can be inadvertently configured with the\nfollowing dm-verity options:\n\n- `CONFIG_DM_VERITY_AVB=y` in the kernel\n- The bootloader configured to use any verity mode, (such as `AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE`), without `AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO`.\n\nWith this device configuration, any verity error causes the vbmeta partition to\nbecome corrupted, and renders non-A/B devices inoperable. Similarly, if a merge\nhas started, A/B devices might also become inoperable. Only use the\n`AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO` verity mode.\n\n1. Set `CONFIG_DM_VERITY_AVB=n` in the kernel.\n2. Configure devices to use the `AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO` mode instead.\n\nFor more information reference the verity documentation: [Handling dm-verity\nErrors](https://android.googlesource.com/platform/external/avb/+/android16-release/README.md#Handling-dm_verity-Errors).\n\n### Confirm the merged file is correctly configured\n\nIf you are building system images and vendor images separately, then using\n`merge_target_files` to merge them, Virtual A/B configurations might be\nincorrectly dropped during the merge process. To verify that Virtual A/B\nconfigurations are correct in the merged target file, apply the following\npatches: [CL\n2084183](https://android-review.googlesource.com/c/platform/build/+/2084183/)\n(merge identical key/val pairs in dynamic partition info)\n\n### Update necessary components\n\nAs of Android 13, `snapuserd` has been moved from vendor ramdisk to generic\nramdisk. If your device is upgrading to Android 13, it is possible that both\nvendor ramdisk and generic ramdisk contain a copy of `snapuserd`. In this\nsituation, Virtual A/B requires the system copy of `snapuserd`. To ensure that\nthe correct copy of `snapuserd` is in place, apply [CL\n2031243](https://android-review.googlesource.com/c/platform/system/core/+/2031243/)\n(copy `snapuserd` to first_stage_ramdisk)."]]