仮想 A/B の実装 - パッチ

以下のパッチを選択して、既知の問題に対処してください。

サイドローディング時に割り当て可能なスペースを正しくチェックする

サイズが 2 × アップデート グループのサイズ合計よりも小さい super パーティションの仮想 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 パーティションを使用していない場合は、boot パーティションまたは recovery パーティションを再ビルドしてフラッシュします。

マージ中のセグメンテーション違反を修正する

OTA アップデートを適用した後、VAB のマージの処理中に update_engine_client --cancel を呼び出すと、CleanupPreviousUpdateAction がクラッシュします。markSlotSuccessful が遅延すると、ワイルド ポインタのエラーが発生する可能性もあります。

これは、StopActionInternal 関数の追加によって解決されました。CleanupPreviousUpdateAction は破棄の際に保留中のタスクをキャンセルします。メッセージ ループ内で保留中のタスクのタスク ID を追跡する変数は維持されます。破棄の際は、セグメンテーション違反の発生を防ぐために、保留中のタスクがキャンセルされます。

マージ中に発生する update_engine での SIGSEGV のクラッシュを修正するには、Android 11 ソースツリーで次の変更を適用します。

  • CL 1439792(CL 1439372 の前提条件)
  • CL 1439372CleanupPreviousUpdateAction: 破棄の際の保留中のタスクのキャンセル)
  • CL 1663460markSlotSuccessful が遅れた場合の潜在的なワイルド ポインタのエラーの修正)

update_engine による早すぎるマージを防ぐ

デバイスが起動され(Android 11 以降)、起動が完了すると、update_engineScheduleWaitMarkBootSuccessful()WaitForMergeOrSchedule() を呼び出します。これにより、マージの処理が開始されます。しかし、デバイスは古いスロットで再起動されます。マージがすでに開始しているため、デバイスは起動できず、動作不能になります。

ソースツリーに次の変更を追加します。CL 1664859 は省略可能です。

  • CL 1439792(CL 1439372 の前提条件)
  • CL 1439372CleanupPreviousUpdateAction: 破棄の際の保留中のタスクのキャンセル)
  • CL 1663460markSlotSuccessful が遅れた場合の潜在的なワイルド ポインタのエラーの修正)
  • CL 1664859(省略可 - CleanupPreviousUpdateActionunittest を追加)

dm-verity の設定が正しいことを確認する

Android 11 以降では、次の dm-verity オプションでデバイスが誤って設定されることがあります。

  • カーネルの CONFIG_DM_VERITY_AVB=y
  • AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO なしで任意の verity モード(AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE など)を使用するように設定されたブートローダー

このデバイス設定では、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(動的パーティション情報内の同一の Key-Value ペアをマージする)というパッチを適用します。

必要なコンポーネントを更新する

Android 13 では、snapuserd をベンダー RAM ディスクから汎用 RAM ディスクに移動しました。デバイスを Android 13 にアップグレードする場合、ベンダー RAM ディスクと汎用 RAM ディスクの両方に snapuserd のコピーが含まれる可能性があります。この場合、仮想 A/B には snapuserd のシステムコピーが必要になります。snapuserd の正しいコピーを確実に配置するには、CL 2031243snapuserd を first_stage_ramdisk にコピーする)を適用します。