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 Startvorgang 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, und die Unterstützung von Key-Versionsbindung und Key-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

Prüfpunktfunktion 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 Prüfpunktfunktion. 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 erforderlich sind, 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 entweder in einem Bootloader-A/B-Status befindet oder die Anzahl der Update-Wiederholungsversuche 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 „Vom Nutzer definierte Klassen“ 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 (z. B. Bilder, Videos, SMS, Serverempfang) in den Nutzerdaten und vor BootComplete geschrieben werden.

Wenn kein aktiver Checkpoint-Update vorhanden ist, hat diese Methode keine Auswirkungen.

abortChanges()

Erzwingt einen Neustart und setzt auf den 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. Es werden Logeinträge 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 als 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 dem Abschnitt <fs_mgr_flags> von fstab für das Gerät, das unter /data gemountet ist, das Flag checkpoint=fs hinzu.

Nicht-F2FS-Systeme

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

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

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.