動的パーティションを使用する A/B デバイス向け OTA

Android 10 は、無線(OTA)アップデート時にパーティションの作成、サイズ変更、破棄を行えるユーザー空間パーティショニング システムである動的パーティションをサポートしています。

このページでは、Android 9 以前を搭載した動的パーティションを使用してリリースした A/B デバイスのアップデート中に動的パーティションのサイズを変更する方法について説明します。

背景

デバイスには super パーティションが 1 つあります。このパーティションにはスロットの接尾辞が付きません。ブロック デバイスは、fstab 内にある /miscblk_device エントリに従っている必要があります。たとえば、fstab ファイルリストが次のような場合を仮定します。

/dev/block/bootdevice/by-name/misc    /misc    # Other fields

この場合、super 用のブロック デバイスは /dev/block/bootdevice/by-name/super に存在する必要があります。ただし、この super パーティションは fstab ファイルにリストされる必要はありません。

super パーティションにはメタデータ スロットが 2 つあります。0 と 1 の番号が振られており、パーティションの A/B スロットに対応します。このドキュメントでは、メタデータ スロットはメタデータ S(ソース)とメタデータ T(ターゲット)と呼びます。同様に、パーティションは system_svendor_t などと呼びます。

アップグレード前のメタデータ S には、使用されている動的パーティションの情報が含まれています。通常は system_svendor_sproduct_s などです。更新中にはこれらのパーティションのエクステントが読み取られるため、削除できません。

パーティションはアップデート グループに属しています。詳しくは動的パーティションの実装をご覧ください。

デバイス上のメタデータの例を次に示します。

  • メタデータ 0
    • グループ foo_a
      • パーティション system_a
      • パーティション product_services_a
      • Foo によって更新されたその他のパーティション
    • グループ bar_a
      • パーティション vendor_a
      • パーティション product_a
      • Bar によって更新されたその他のパーティション
    • グループ foo_b(以前のアップグレードからの残り)
    • グループ bar_b(以前のアップグレードからの残り)
  • メタデータ 1
    • グループ foo_a(以前のアップグレードからの残り)
    • グループ bar_a(以前のアップグレードからの残り)
    • グループ foo_b
      • パーティション system_b
      • パーティション product_services_b
      • Foo によって更新されたその他のパーティション
    • グループ bar_b
      • パーティション vendor_b
      • パーティション product_b
      • Bar によって更新されたその他のパーティション

lpdump ツール(system/extras/partition_tools にあるソースコード)を使用して、デバイスにメタデータをダンプできます。次に例を示します。

lpdump --slot 0 /dev/block/bootdevice/by-name/super
lpdump --slot 1 /dev/block/bootdevice/by-name/super

更新フロー

  1. super パーティション メタデータを初期化します。
    1. メタデータ S からソースの動的パーティションのエクステントを読み込みます。読み込まれたメタデータを M とします。
    2. foo_tbar_t などのターゲット グループとパーティションを M から削除し、M には _s 接尾辞の付いたパーティションとグループのみが含まれるようにします。
    3. アップデート マニフェストの dynamic_partition_metadata フィールドに従ってターゲット グループとパーティションを追加します。
      各パーティションのサイズは、new_partition_info にあります。
    4. M をメタデータ T に書き込みます。
    5. デバイス マッパー上に追加されたパーティションを書き込み可能としてマッピングします。
  2. ブロック デバイスにアップデートを適用します。
    1. 必要に応じて、デバイス マッパー上のソース パーティションを読み取り専用としてマッピングします。更新前にはソース パーティションがマッピングされていないため、サイドローディングにはこのマッピングが必要です。
    2. ターゲット スロットのすべてのブロック デバイスにフル アップデートまたは差分アップデートを適用します。
    3. パーティションをマウントしてインストール後のスクリプトを実行し、パーティションをマウント解除します。
  3. ターゲット パーティションのマッピングを解除します。

更新の前後に、次のシステム プロパティにそれぞれの値を設定します。

ro.boot.dynamic_partitions=true
ro.boot.dynamic_partitions_retrofit=true

アップデート マニフェストにグループとパーティションを追加する

動的パーティションを使用する A/B デバイス、または動的パーティションのサポートを追加した A/B デバイスで OTA アップデートを行う場合は、グループとパーティションをアップデート マニフェストに追加する必要があります。以下のスニペットは、動的パーティションをサポートするためのアップデート マニフェストに関する追加情報を示しています。各フィールドの詳細については、update_metadata.proto をご覧ください。

message DeltaArchiveManifest {
    optional DynamicPartitionMetadata dynamic_partition_metadata;
}

message DynamicPartitionMetadata {
    repeated DynamicPartitionGroup groups;
}

message DynamicPartitionGroup {
    required string name;
    optional uint64 size; // maximum size of group
    repeated string partition_names;
}