Prüfpunkt für Nutzerdaten

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

Mit UDC kann die Nutzerdatenpartition auch nach der Änderung wiederhergestellt werden. Die UDC-Funktion erreicht dies mit Prüfpunktfunktionen für das Dateisystem, einer alternativen Implementierung, wenn das Dateisystem keine Prüfpunkte unterstützt, der Integration mit dem A/B-Mechanismus des Bootloaders und der Unterstützung von Nicht-A/B-Updates sowie der Unterstützung für die Bindung der Schlüsselversion und die Verhinderung von Schlüssel-Rollbacks.

Auswirkungen auf Nutzer

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

Funktionsweise

Prüfpunktfunktion in verschiedenen Dateisystemen

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

Für andere Dateisysteme verwendet UDC ein virtuelles Gerät des Gerätemanagers namens dm_bow für die Prüfpunktfunktion. dm_bow befindet sich zwischen dem Gerät und dem Dateisystem. Wenn eine Partition gemountet wird, wird ein Trim-Befehl ausgegeben, wodurch das Dateisystem Trim-Befehle für alle kostenlosen Blöcke ausgibt. dm_bow fängt diese Trim-Befehle ab und verwendet sie, um eine Liste kostenloser Blöcke 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 erforderlich sind, in einem kostenlosen Block gesichert.

Prüfpunktvorgang

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 zu ermitteln, ob sich das Gerät in einem A/B-Zustand des Bootloaders befindet oder die Anzahl der Updateversuche festgelegt wurde. Wenn eine der beiden Bedingungen erfüllt ist, ruft Android createCheckpoint auf, um Mount-Flags hinzuzufügen oder ein dm_bow-Gerät zu erstellen.

Nachdem die Partition gemountet wurde, wird der Prüfpunktcode aufgerufen, um Trim-Befehle auszugeben. Der Startvorgang wird dann wie gewohnt fortgesetzt. Bei LOCKED_BOOT_COMPLETE ruft Android commitCheckpoint auf, um den aktuellen Prüfpunkt zu bestätigen. Das Update wird wie gewohnt fortgesetzt.

KeyMint-Schlüssel (ehemals 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 bestätigt wurde.

Zustand überwachen

Ein Systemdiagnose-Daemon prüft, ob genügend Speicherplatz vorhanden ist, um einen Prüfpunkt zu erstellen. Der Systemdiagnose-Daemon befindet sich in cp_healthDaemon in Checkpoint.cpp.

Der Systemdiagnose-Daemon hat die folgenden konfigurierbaren Verhaltensweisen:

Prüfpunkt-APIs

Prüfpunkt-APIs werden von der UDC-Funktion verwendet. Weitere 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 es bereit ist, ein Update zu starten. Der Prüfpunkt wird erstellt, bevor Prüfpunkt-Dateisysteme wie Nutzerdaten nach dem Neustart mit Lese-/Schreibzugriff gemountet werden. Wenn die Anzahl der Versuche positiv ist, verfolgt die API die Versuche und das Updater-Tool ruft needsRollback auf, um zu prüfen, ob ein Rollback des Updates erforderlich ist. Wenn die Anzahl der Versuche -1 ist, überlässt die API die Entscheidung dem A/B-Bootloader.

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

void commitChanges()

Bestätigt die Änderungen.

Das Framework ruft diese Methode nach dem Neustart auf, wenn die Änderungen bestätigt werden können. Sie wird aufgerufen, bevor Daten (z. B. Bilder, Videos, SMS, Serverbestätigung des Empfangs) in die Nutzerdaten geschrieben werden und vor BootComplete.

Wenn kein aktives Prüfpunkt-Update vorhanden ist, hat diese Methode keine Auswirkungen.

abortChanges()

Erzwingt einen Neustart und setzt auf den Prüfpunkt zurück. Verwirft alle Änderungen an den Nutzerdaten seit dem ersten Neustart.

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()

Ermittelt, ob ein Rollback erforderlich ist.

Gibt auf Geräten ohne Prüfpunktfunktion false zurück. Gibt auf Geräten mit Prüfpunktfunktion während eines Starts ohne Prüfpunktfunktion true zurück.

UDC implementieren

Referenzimplementierung

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

Einrichtung

Prüfen Sie in on fs in der Datei init.hardware.rc, ob Folgendes vorhanden ist:

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

Prüfen Sie in on late-fs in der Datei init.hardware.rc, ob Folgendes vorhanden ist:

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

Prüfen Sie in der Datei fstab.hardware, ob /data als latemount getaggt 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, um die Anzahl der Versuche ohne Bootloader und Schlüssel zu speichern. Richten Sie eine Metadatenpartition ein und mounten Sie sie früh unter /metadata.

Prüfen Sie in der Datei fstab.hardware, ob /metadata als earlymount oder first_stage_mount getaggt 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

Achten Sie bei Systemen, die F2FS zum Formatieren von Daten verwenden, darauf, dass Ihre Version von F2FS Prüfpunkte unterstützt. Weitere Informationen finden Sie unter Prüfpunktfunktion in verschiedenen Dateisystemen.

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

Nicht-F2FS-Systeme

Bei Nicht-F2FS-Systemen muss dm-bow in der Kernelkonfiguration aktiviert sein.

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

Logs prüfen

Logeinträge werden generiert, wenn Prüfpunkt-APIs aufgerufen werden.

Validierung

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