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:
ro.sys.cp_msleeptime: Steuert, wie oft das Gerät die Festplattennutzung prüft.ro.sys.cp_min_free_bytes: Steuert den Mindestwert, nach dem der Systemdiagnose-Daemon sucht.ro.sys.cp_commit_on_full: Steuert, ob der Systemdiagnose-Daemon das Gerät neu startet oder den Prüfpunkt bestätigt und fortfährt, wenn die Festplatte voll ist.
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.