Prüfpunkt für Nutzerdaten

Mit Android 10 wird der Nutzerdaten-Prüfpunkt (User Data Checkpoint, UDC) eingeführt, mit dem Android bei einem fehlgeschlagenen Over-the-Air-Update (OTA) auf den vorherigen Zustand zurückgesetzt werden kann. Wenn ein Android-OTA-Update mit UDC fehlschlägt, kann das Gerät sicher auf den vorherigen Zustand zurückgesetzt werden. Obwohl A/B-Updates dieses Problem für den frühen Bootvorgang beheben, wird das Rollback nicht unterstützt, wenn die Partition mit Nutzerdaten (auf /data gemountet) geändert wird.

Mit UDC kann die Partition mit Nutzerdaten auch nach der Änderung wiederhergestellt werden. Die UDC-Funktion erreicht dies durch Checkpoint-Funktionen für das Dateisystem, eine alternative Implementierung, wenn das Dateisystem keine Checkpoints unterstützt, die Integration in den Bootloader-A/B-Mechanismus, während auch Nicht-A/B-Updates unterstützt werden, sowie die Unterstützung von Schlüsselversionsbindung und Schlüssel-Rollback-Schutz.

Auswirkungen auf Nutzer

Die Funktion „UDC“ verbessert die OTA-Update-Erfahrung für Nutzer, da weniger Nutzer ihre Daten verlieren, wenn ein OTA-Update fehlschlägt. So kann die Anzahl der Supportanrufe von Nutzern, die während des Aktualisierungsvorgangs auf Probleme stoßen, reduziert werden. Wenn ein OTA-Update fehlschlägt, kann es jedoch sein, dass das Gerät mehrmals neu startet.

Funktionsweise

Checkpoint-Funktion in verschiedenen Dateisystemen

Für das F2FS-Dateisystem fügt UDC dem Upstream-Linux-Kernel 4.20 die Checkpoint-Funktion hinzu und portiert sie auf alle gängigen Kernel zurück, die von Geräten mit Android 10 unterstützt werden.

Bei anderen Dateisystemen verwendet UDC ein virtuelles Device Mapper-Gerät namens dm_bow für die Checkpoint-Funktionalität. dm_bow befindet sich zwischen dem Gerät und dem Dateisystem. Wenn eine Partition bereitgestellt wird, wird ein TRIM-Befehl ausgegeben, der das Dateisystem dazu veranlasst, TRIM-Befehle für alle kostenlosen Blöcke auszugeben. dm_bow fängt diese Trims ab und verwendet sie, um eine Liste mit kostenlosen Blöcken einzurichten. Lese- und Schreibvorgänge werden dann unverändert an das Gerät gesendet. Bevor ein Schreibvorgang zulässig ist, werden jedoch Daten, die für eine Wiederherstellung benötigt werden, in einem kostenlosen Block gesichert.

Prüfpunktverfahren

Wenn eine Partition mit dem Flag checkpoint=fs/block gemountet wird, ruft Android restoreCheckpoint auf dem Laufwerk auf, damit das Gerät einen aktuellen Prüfpunkt wiederherstellen kann. init ruft dann die Funktion needsCheckpoint auf, um festzustellen, ob sich das Gerät in einem Bootloader-A/B-Status befindet oder die Anzahl der Update-Wiederholungen festgelegt wurde. Wenn eine der beiden Bedingungen zutrifft, ruft Android createCheckpoint auf, um entweder Mount-Flags hinzuzufügen oder ein dm_bow-Gerät zu erstellen.

Nachdem die Partition gemountet wurde, wird der Prüfpunktcode aufgerufen, um Trims auszugeben. Der Startvorgang wird dann wie gewohnt fortgesetzt. Bei LOCKED_BOOT_COMPLETE ruft Android commitCheckpoint auf, um den aktuellen Checkpoint zu übernehmen. Die Aktualisierung wird wie gewohnt fortgesetzt.

KeyMint-Schlüssel (früher Keymaster) verwalten

KeyMint-Schlüssel werden für die Geräteverschlüsselung oder andere Zwecke verwendet. Um diese Schlüssel zu verwalten, verzögert Android Aufrufe zum Löschen von Schlüsseln, bis der Prüfpunkt festgeschrieben wird.

Gesundheit im Blick behalten

Ein Health-Daemon prüft, ob genügend Speicherplatz zum Erstellen eines Prüfpunkts vorhanden ist. Der Health-Daemon befindet sich in cp_healthDaemon in Checkpoint.cpp.

Der Health-Daemon hat die folgenden Verhaltensweisen, die konfiguriert werden können:

Checkpoint-APIs

Checkpoint-APIs werden von der Funktion „Nutzerdefinierte Inhalte“ verwendet. Informationen zu anderen APIs, die von UDC verwendet werden, finden Sie unter IVold.aidl.

void startCheckpoint(int retry)

Erstellt einen Prüfpunkt.

Das Framework ruft diese Methode auf, wenn ein Update gestartet werden kann. Der Prüfpunkt wird erstellt, bevor Prüfpunktdateisysteme wie „userdata“ nach dem Neustart mit Lese-/Schreibzugriff gemountet werden. Wenn die Anzahl der Wiederholungsversuche positiv ist, verarbeitet die API die Tracking-Wiederholungsversuche und der Updater ruft needsRollback auf, um zu prüfen, ob ein Rollback des Updates erforderlich ist. Wenn die Anzahl der Wiederholungsversuche -1 ist, wird die Entscheidung dem A/B-Bootloader überlassen.

Diese Methode wird bei einem normalen A/B-Update nicht aufgerufen.

void commitChanges()

Führt ein Commit der Änderungen durch.

Das Framework ruft diese Methode nach dem Neustart auf, wenn die Änderungen übernommen werden können. Diese Funktion wird aufgerufen, bevor Daten wie Bilder, Videos, SMS und der Serverempfang in die Nutzerdaten geschrieben werden und vor BootComplete.

Wenn kein aktives Update mit Checkpoint vorhanden ist, hat diese Methode keine Auswirkungen.

abortChanges()

Erzwingt einen Neustart und kehrt zum Prüfpunkt zurück. Alle Änderungen an Nutzerdaten seit dem ersten Neustart werden verworfen.

Das Framework ruft diese Methode nach dem Neustart, aber vor commitChanges auf. retry_counter wird verringert, wenn diese Methode aufgerufen wird. Logeinträge werden generiert.

bool needsRollback()

Bestimmt, ob ein Rollback erforderlich ist.

Gibt auf Geräten ohne Checkpoint false zurück. Auf Checkpoint-Geräten wird true bei einem Bootvorgang ohne Checkpoint zurückgegeben.

UDC implementieren

Referenzimplementierung

Ein Beispiel für die Implementierung von UDC finden Sie unter dm-bow.c. Weitere Informationen zu dieser Funktion finden Sie unter dm-bow.txt.

Einrichten

Achten Sie darauf, dass in on fs in Ihrer init.hardware.rc-Datei Folgendes enthalten ist:

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

Achten Sie darauf, dass in on late-fs in Ihrer init.hardware.rc-Datei Folgendes enthalten ist:

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

Achten Sie darauf, dass in der Datei fstab.hardware /data als latemount gekennzeichnet ist.

/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

Metadatenpartition hinzufügen

UDC erfordert eine Metadatenpartition zum Speichern der Anzahl der Wiederholungsversuche ohne Bootloader und der Schlüssel. Richten Sie eine Metadatenpartition ein und hängen Sie sie frühzeitig unter /metadata ein.

Achten Sie darauf, dass in der Datei fstab.hardware /metadata mit earlymount oder first_stage_mount gekennzeichnet ist.

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

Initialisieren Sie die Partition mit Nullen.

Fügen Sie BoardConfig.mk die folgenden Zeilen hinzu:

BOARD_USES_METADATA_PARTITION := true
BOARD_ROOT_EXTRA_FOLDERS := existing_folders metadata

Systeme aktualisieren

F2FS-Systeme

Bei Systemen, die F2FS zum Formatieren von Daten verwenden, muss Ihre Version von F2FS Checkpoints unterstützen. Weitere Informationen finden Sie unter Checkpoint-Funktion in verschiedenen Dateisystemen.

Fügen Sie das Flag checkpoint=fs dem Abschnitt <fs_mgr_flags> von fstab für das Gerät hinzu, das unter /data gemountet ist.

Nicht-F2FS-Systeme

Bei Systemen, die nicht F2FS verwenden, muss dm-bow in der Kernelkonfiguration aktiviert sein.

Fügen Sie das Flag checkpoint=block dem Abschnitt <fs_mgr_flags> von fstab für das Gerät hinzu, das unter /data gemountet ist.

Logs prüfen

Logeinträge werden generiert, wenn Checkpoint APIs aufgerufen werden.

Zertifizierungsstufe

Führen Sie die VtsKernelCheckpointTest-VTS-Tests aus, um Ihre UDC-Implementierung zu testen.