Android 10 führt den User Data Checkpoint (UDC) ein, der es Android ermöglicht, auf seinen vorherigen Zustand zurückzusetzen, wenn ein Android-Over-the-Air-Update (OTA) fehlschlägt. Wenn ein Android-OTA-Update fehlschlägt, kann das Gerät mit UDC sicher in den vorherigen Zustand zurückgesetzt werden. Obwohl A/B-Updates dieses Problem für den frühen Start lösen, wird ein Rollback nicht unterstützt, wenn die Benutzerdatenpartition (gemountet auf /data
) geändert wird.
Mit UDC kann das Gerät die Benutzerdatenpartition auch nach einer Änderung wiederherstellen. Die UDC-Funktion erreicht dies mit Checkpoint-Funktionen für das Dateisystem, einer alternativen Implementierung, wenn das Dateisystem keine Checkpoints unterstützt, Integration mit dem A/B-Mechanismus des Bootloaders bei gleichzeitiger Unterstützung von Nicht-A/B-Updates und Unterstützung für die Schlüsselversionsbindung und Schlüssel-Rollback-Verhinderung.
Auswirkungen auf den Benutzer
Die UDC-Funktion verbessert das OTA-Update-Erlebnis für Benutzer, da weniger Benutzer ihre Daten verlieren, wenn ein OTA-Update fehlschlägt. Dies kann die Anzahl der Supportanrufe von Benutzern reduzieren, die während des Aktualisierungsprozesses auf Probleme stoßen. Wenn jedoch ein OTA-Update fehlschlägt, bemerken Benutzer möglicherweise, dass das Gerät mehrmals neu startet.
Wie es funktioniert
Checkpoint-Funktionalität in verschiedenen Dateisystemen
Für das F2FS-Dateisystem fügt UDC die Checkpoint-Funktionalität zum 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 Device-Mapper-Gerät namens dm_bow
für die Checkpoint-Funktionalität. dm_bow
sitzt zwischen dem Gerät und dem Dateisystem. Wenn eine Partition gemountet wird, wird eine Kürzung ausgegeben, die das Dateisystem dazu veranlasst, Kürzungsbefehle für alle freien Blöcke auszugeben. dm_bow
fängt diese Trims ab und verwendet sie, um eine freie Blockliste einzurichten. Lese- und Schreibvorgänge werden dann unverändert an das Gerät gesendet. Bevor jedoch ein Schreibvorgang zulässig ist, werden die für eine Wiederherstellung erforderlichen Daten in einem freien Block gesichert.
Checkpoint-Prozess
Wenn eine Partition mit dem Flag checkpoint=fs/block
gemountet wird, ruft Android restoreCheckpoint
auf dem Laufwerk auf, damit das Gerät jeden 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 Aktualisierungswiederholungen festgelegt hat. Wenn einer von beiden 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 Kürzungen vorzunehmen. Der Bootvorgang wird dann wie gewohnt fortgesetzt. Bei LOCKED_BOOT_COMPLETE
ruft Android commitCheckpoint
auf, um den aktuellen Prüfpunkt festzuschreiben, und das Update wird wie gewohnt fortgesetzt.
Keymaster-Schlüssel verwalten
Keymaster-Schlüssel werden zur Geräteverschlüsselung oder für andere Zwecke verwendet. Um diese Schlüssel zu verwalten, verzögert Android Aufrufe zum Löschen von Schlüsseln, bis der Prüfpunkt festgeschrieben ist.
Überwachen Sie die Gesundheit
Ein Integritätsdämon überprüft, ob genügend Speicherplatz zum Erstellen eines Prüfpunkts vorhanden ist. Der Gesundheitsdämon befindet sich in cp_healthDaemon
in Checkpoint.cpp
.
Der Gesundheitsdämon verfügt über die folgenden Verhaltensweisen, die konfiguriert werden können:
-
ro.sys.cp_msleeptime
: Steuert, wie oft das Gerät die Festplattennutzung überprüft. -
ro.sys.cp_min_free_bytes
: Steuert den Mindestwert, nach dem der Gesundheitsdämon sucht. -
ro.sys.cp_commit_on_full
: Steuert, ob der Integritätsdämon das Gerät neu startet oder den Prüfpunkt festschreibt und fortfährt, wenn die Festplatte voll ist.
Checkpoint-APIs
Checkpoint-APIs werden von der UDC-Funktion verwendet. Weitere von UDC verwendete APIs 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 mit Prüfpunkten versehene Dateisysteme wie Benutzerdaten nach dem Neustart R/W gemountet werden. Wenn die Anzahl der Wiederholungen positiv ist, verarbeitet die API Nachverfolgungswiederholungen und der Updater ruft needsRollback
auf, um zu prüfen, ob ein Rollback des Updates erforderlich ist. Wenn die Anzahl der Wiederholungen -1
beträgt, verlässt sich die API auf die Beurteilung des A/B-Bootloaders.
Diese Methode wird bei einem normalen A/B-Update nicht aufgerufen.
void commitChanges()
Überträgt die Änderungen.
Das Framework ruft diese Methode nach dem Neustart auf, wenn die Änderungen zum Festschreiben bereit sind. Dies wird aufgerufen, bevor Daten (z. B. Bilder, Videos, SMS, Empfangsbestätigungen des Servers) in die Benutzerdaten geschrieben werden und vor BootComplete
.
Wenn kein aktives Checkpoint-Update vorhanden ist, hat diese Methode keine Auswirkung.
abortChanges()
Erzwingt einen Neustart und kehrt zum Prüfpunkt zurück. Verwirft alle Benutzerdatenänderungen 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. Es werden Protokolleinträge generiert.
bool brauchtRollback()
Bestimmt, ob ein Rollback erforderlich ist.
Auf Nicht-Checkpoint-Geräten wird false
zurückgegeben. Auf Checkpoint-Geräten wird bei einem Nicht-Checkpoint-Start true
zurückgegeben.
Implementieren Sie UDC
Referenzimplementierung
Ein Beispiel dafür, wie UDC implementiert werden kann, finden Sie unter dm-bow.c . Weitere Dokumentation zu dieser Funktion finden Sie unter dm-bow.txt .
Aufstellen
Stellen Sie unter on fs
in Ihrer init.hardware.rc
Datei sicher, dass Folgendes vorhanden ist:
mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --early
Stellen Sie on late-fs
in Ihrer init.hardware.rc
Datei sicher, dass Folgendes vorhanden ist:
mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --late
Stellen Sie in Ihrer fstab.hardware
Datei sicher, /data
mit 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 und Schlüssel der Nicht-Bootloader-Wiederholungen. Richten Sie eine Metadatenpartition ein und mounten Sie sie frühzeitig unter /metadata
.
Stellen Sie in Ihrer fstab.hardware
Datei sicher, /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 ausschließlich mit Nullen.
Fügen Sie die folgenden Zeilen zu BoardConfig.mk
hinzu:
BOARD_USES_METADATA_PARTITION := true BOARD_ROOT_EXTRA_FOLDERS := existing_folders metadata
Systeme aktualisieren
F2FS-Systeme
Stellen Sie bei Systemen, die F2FS zum Formatieren von Daten verwenden, sicher, dass Ihre Version von F2FS Prüfpunkte unterstützt. Weitere Informationen finden Sie unter Checkpoint-Funktionalität in verschiedenen Dateisystemen .
Fügen Sie das Flag checkpoint=fs
zum Abschnitt <fs_mgr_flags>
von fstab für das unter /data
gemountete Gerät hinzu.
Nicht-F2FS-Systeme
Für Nicht-F2FS-Systeme muss dm-bow
in der Kernel-Konfiguration aktiviert sein.
Fügen Sie das Flag checkpoint=block
zum Abschnitt <fs_mgr_flags>
von fstab für das unter /data
gemountete Gerät hinzu.
Protokolle prüfen
Beim Aufruf von Checkpoint-APIs werden Protokolleinträge generiert.
Validierung
Um Ihre UDC-Implementierung zu testen, führen Sie den VtsKernelCheckpointTest
Satz von VTS-Tests aus.