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:
ro.sys.cp_msleeptime
: Gibt an, wie oft das Gerät die Festplattennutzung prüft.ro.sys.cp_min_free_bytes
: Steuert den Mindestwert, nach dem der Health-Daemon sucht.ro.sys.cp_commit_on_full
: Steuert, ob der Health-Daemon das Gerät neu startet oder den Checkpoint übergibt und fortfährt, wenn das Laufwerk voll ist.
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.