ユーザーデータ チェックポイント

Android 10 では、ユーザーデータ チェックポイント(UDC)が導入され、Android 無線(OTA)アップデートが失敗したときに以前の状態にロールバックできるようになりました。UDC を使用している場合、Android OTA アップデートが失敗すると、デバイスは以前の状態に安全にロールバックできます。この問題は A/B アップデートによりアーリーブートについては解決されていますが、ユーザーデータ パーティション(/data にマウントされています)が変更された場合のロールバックはサポートされていません。

UDC により、デバイスはユーザーデータ パーティションが変更された後でも復元できます。UDC 機能がこれを実現する仕組みを支えているのは、ファイル システムに対するチェックポイント機能、ファイル システムがチェックポイントをサポートしていない場合の代替実装、ブートローダー A/B メカニズムの統合(非 A/B アップデートにも対応)、鍵バージョンのバインディングおよび鍵のロールバック防止のサポートです。

ユーザーへの影響

UDC 機能により、OTA アップデートが失敗してもユーザーがデータを失うことが少なくなるので、OTA アップデートの利便性が向上します。これにより、アップデート プロセス中に問題が発生したユーザーからのサポート依頼の電話を減らすことができます。ただし、OTA アップデートが失敗したとき、デバイスが何度も再起動されることにユーザーが気づく可能性があります。

仕組み

各種のファイル システムにおけるチェックポイント機能

F2FS ファイル システムの場合、UDC はアップストリームの 4.20 Linux カーネルにチェックポイント機能を追加し、Android 10 を搭載したデバイスでサポートされるすべての一般的なカーネルにバックポートします。

他のファイル システムでは、UDC は dm_bow と呼ばれるデバイス マッパー仮想デバイスを使用してチェックポイント機能を提供します。dm_bow は、デバイスとファイル システムの間で動作します。パーティションがマウントされると trim が発行され、それによりファイル システムはすべての空きブロックで trim コマンドを発行するようになります。dm_bow は trim コマンドをインターセプトし、それを使用して空きブロックリストを設定します。読み取りと書き込みは変更されずにデバイスに送信されますが、書き込みが許可される前に、復元に必要なデータが空きブロックにバックアップされます。

チェックポイント処理

checkpoint=fs/block フラグの付いたパーティションがマウントされると、Android はそのドライブ上で restoreCheckpoint を呼び出して、デバイスが現在のチェックポイントを復元できるようにします。次に、initneedsCheckpoint 関数を呼び出し、デバイスがブートローダー A/B 状態にあるか、アップデートの再試行回数が設定されているかを判定します。いずれかが true の場合、Android は createCheckpoint を呼び出してマウントフラグを追加するか、dm_bow デバイスをビルドします。

パーティションのマウントが完了すると、trim を発行するためにチェックポイント コードが呼び出されます。その後、起動プロセスが通常どおり続行されます。LOCKED_BOOT_COMPLETE の際は、Android が commitCheckpoint を呼び出して現在のチェックポイントを commit します。アップデートは通常どおり続行されます。

Keymaster キーを管理する

Keymaster キーはデバイスの暗号化などに使用されます。これらのキーを管理するため、チェックポイントが commit されるまで Android はキー削除呼び出しを遅延させます。

正常性をモニタリングする

ヘルスデーモンは、チェックポイントを作成するために十分なディスク容量があるかどうかを確認します。ヘルスデーモンは Checkpoint.cpp 内の cp_healthDaemon にあります。

ヘルスデーモンには、次のような動作を設定できます。

  • ro.sys.cp_msleeptime: デバイスがディスク使用量をチェックする頻度を制御します。
  • ro.sys.cp_min_free_bytes: ヘルスデーモンが検索する最小値を制御します。
  • ro.sys.cp_commit_on_full: ディスクがいっぱいになったときに、ヘルスデーモンがデバイスを再起動するか、チェックポイントを commit して続行するかを制御します。

チェックポイント API

チェックポイント API は UDC 機能で使用されます。UDC で使用されるその他の API については、IVold.aidl をご覧ください。

void startCheckpoint(int retry)

チェックポイントを作成します。

フレームワークは、アップデートを開始する準備が整うと、このメソッドを呼び出します。チェックポイントは、再起動後にユーザーデータなどのチェックポイント付きファイル システムが R/W マウントされる前に、作成されます。retry の数値が正の場合、API は再試行回数のトラッキングを処理し、アップデータは needsRollback を呼び出してアップデートのロールバックが必要かどうかを確認します。retry の数値が -1 の場合、API は A/B ブートローダーの判断に従います。

このメソッドは、通常の A/B アップデートを実行するときは呼び出されません。

void commitChanges()

変更を commit します。

変更が commit 可能になると、フレームワークは再起動後にこのメソッドを呼び出します。このメソッドは、画像、動画、SMS、サーバー受信などのデータがユーザーデータに書き込まれる前、および BootComplete の前に呼び出されます。

有効なチェックポイント付きアップデートが存在しない場合、このメソッドは効力がありません。

abortChanges()

強制的に再起動し、チェックポイントに戻ります。最初の再起動以降に行われた、ユーザーデータのすべての変更を破棄します。

フレームワークは、再起動の後、commitChanges の前にこのメソッドを呼び出します。このメソッドが呼び出されると、retry_counter が減ります。ログエントリが生成されます。

bool needsRollback()

ロールバックが必要かどうかを判断します。

チェックポイントがないデバイスでは、false を返します。チェックポイントがあるデバイスでは、チェックポイントがない起動の場合に true を返します。

UDC を実装する

リファレンス実装

UDC を実装する方法の例については、dm-bow.c をご覧ください。この機能の詳細については、dm-bow.txt をご覧ください。

セットアップ

init.hardware.rc ファイルの on fs では次のようにしてください。

mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --early

init.hardware.rc ファイルの on late-fs では次のようにしてください。

mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --late

fstab.hardware ファイルでは /datalatemount のタグが付くようにしてください。

/dev/block/bootdevice/by-name/userdata              /data              f2fs
noatime,nosuid,nodev,discard,reserve_root=32768,resgid=1065,fsync_mode=nobarrier
latemount,wait,check,fileencryption=ice,keydirectory=/metadata/vold/metadata_encryption,quota,formattable,sysfs_path=/sys/devices/platform/soc/1d84000.ufshc,reservedsize=128M,checkpoint=fs

メタデータ パーティションを追加する

UDC には、非ブートローダーの再試行回数とキーを格納するメタデータ パーティションが必要です。メタデータ パーティションを設定して、/metadata に早期マウントします。

fstab.hardware ファイルで、/metadataearlymount または first_stage_mount のタグを付けてください。

/dev/block/by-name/metadata           /metadata           ext4
noatime,nosuid,nodev,discard,sync
wait,formattable,first_stage_mount

パーティションをすべてゼロに初期化します。

BoardConfig.mk に、次の行を追加します。

BOARD_USES_METADATA_PARTITION := true
BOARD_ROOT_EXTRA_FOLDERS := existing_folders metadata

システムを更新する

F2FS システム

データをフォーマットするために F2FS を使用しているシステムでは、F2FS のバージョンがチェックポイントに対応していることを確認してください。詳細については、各種のファイル システムにおけるチェックポイント機能をご覧ください。

/data にマウントされているデバイスに対して、fstab の <fs_mgr_flags> セクションに checkpoint=fs フラグを追加します。

F2FS 以外のシステム

F2FS 以外のシステムでは、dm-bow がカーネル構成で有効になっている必要があります。

/data にマウントされているデバイスに対して、fstab の <fs_mgr_flags> セクションに checkpoint=block フラグを追加します。

ログを確認する

チェックポイント API が呼び出されると、ログエントリが生成されます。

検証

UDC の実装をテストするには、VTS テストの VtsKernelCheckpointTest セットを実施します。