Checkpoint dei dati utente

Android 10 introduce il controllo dei dati utente (UDC), che consente ad Android di eseguire il rollback allo stato precedente quando un aggiornamento over-the-air (OTA) di Android non va a buon fine. Con UDC, se un aggiornamento OTA di Android non va a buon fine, il dispositivo può eseguire il rollback allo stato precedente in tutta sicurezza. Sebbene Gli aggiornamenti A/B risolvono il problema per l'avvio anticipato e il rollback non è supportata quando la partizione dei dati utente (montata su /data) viene modificata.

L'UDC consente al dispositivo di ripristinare la partizione dei dati utente anche dopo modificato. La funzionalità UDC lo ottiene con le funzionalità di checkpoint per il file system, un'implementazione alternativa quando il file system non supporta i checkpoint, l'integrazione con il meccanismo A/B del bootloader e supporta anche gli aggiornamenti non A/B, nonché il supporto per il binding delle versioni delle chiavi e la prevenzione del rollback delle chiavi.

Impatto sugli utenti

La funzionalità UDC migliora l'esperienza di aggiornamento OTA per gli utenti, poiché meno utenti perdono i propri dati quando un aggiornamento OTA non va a buon fine. Ciò può ridurre il numero di chiamate di assistenza dagli utenti che riscontrano problemi durante il processo di aggiornamento. Tuttavia, quando un aggiornamento OTA non va a buon fine, gli utenti potrebbero notare che il dispositivo si riavvia più volte.

Come funziona

Funzionalità di checkpoint in diversi file system

Per il file system F2FS, UDC aggiunge la funzionalità di checkpoint al kernel Linux 4.20 upstream e la esegue il backport a tutti i kernel comuni supportati dai dispositivi con Android 10.

Per altri file system, UDC utilizza un dispositivo virtuale mapper dei dispositivi denominato dm_bow per la funzionalità di checkpoint. dm_bow si trova tra il dispositivo e il sistema file. Quando una partizione viene montata, viene generato un taglio che fa sì che il file system emette comandi di ritaglio su tutti i blocchi liberi. dm_bow intercetta questi ritagli e usa per creare una lista bloccata senza costi. Le letture e le scritture vengono quindi inviate al dispositivo senza modifiche, ma prima che una scrittura sia consentita, viene eseguito il backup dei dati necessari per un ripristino in un blocco libero.

Processo di checkpoint

Quando viene montata una partizione con il flag checkpoint=fs/block, Android chiama restoreCheckpoint sull'unità per consentire al dispositivo di ripristinare lo stato attuale punto di controllo. init chiama quindi la funzione needsCheckpoint per determinare se il dispositivo è in stato A/B del bootloader o ha impostato un nuovo tentativo di aggiornamento conteggio. Se una delle due condizioni è vera, Android chiama createCheckpoint per aggiungere i flag di montaggio o per creare un dispositivo dm_bow.

Dopo aver montato la partizione, il codice del checkpoint viene chiamato per emettere i ritagli. Il processo di avvio continua quindi normalmente. Presso LOCKED_BOOT_COMPLETE, Android chiama commitCheckpoint per eseguire il commit del checkpoint attuale e dell'aggiornamento continua normalmente.

Gestire le chiavi keymaster

Le chiavi Keymaster vengono utilizzate per la crittografia dei dispositivi o per altri scopi. Per gestire queste chiavi, Android ritarda le chiamate di eliminazione delle chiavi fino al commit del checkpoint.

Monitorare lo stato di salute

Un daemon di stato verifica che sia disponibile spazio su disco sufficiente per creare un checkpoint. Il daemon relativo alla salute si trova cp_healthDaemon tra Checkpoint.cpp.

Il daemon di integrità ha i seguenti comportamenti che possono essere configurati:

  • ro.sys.cp_msleeptime: controlla la frequenza con cui il dispositivo controlla l'utilizzo del disco.
  • ro.sys.cp_min_free_bytes: Controlla il valore minimo cercato dal daemon di integrità.
  • ro.sys.cp_commit_on_full: controlla se il daemon di salute riavvia il dispositivo o esegue il commit del checkpoint e continua quando il disco è pieno.

API di controllo

Le API di controllo vengono utilizzate dalla funzionalità UDC. Per altre API utilizzate dall'UDC, vedi IVold.aidl

void startCheckpoint(int riprova)

Crea un checkpoint.

Il framework chiama questo metodo quando è pronto per avviare un aggiornamento. La il checkpoint viene creato prima che i file system con checkpoint come i dati utente vengano montato R/W dopo il riavvio. Se il conteggio dei tentativi è positivo, l'API gestisce il monitoraggio dei tentativi e l'aggiornamento chiama needsRollback per verificare se è necessario un rollback dell'aggiornamento. Se il conteggio dei tentativi di ripetizione è -1, l'API rimanda al giudizio del bootloader A/B.

Questo metodo non viene chiamato quando si esegue un normale aggiornamento A/B.

void commitChanges()

Esegue il commit delle modifiche.

Il framework chiama questo metodo dopo il riavvio quando le modifiche sono pronte per essere committate. Viene chiamato prima che i dati (ad esempio immagini, video, SMS, conferma di ricezione del server) vengano scritti in userdata e prima di BootComplete.

Se non esiste alcun aggiornamento con controllo attivo, questo metodo non ha alcun effetto.

abortChanges()

Forza il riavvio e ripristina il checkpoint. Abbandona tutte le modifiche ai dati utente dall'ultimo riavvio.

Il framework chiama questo metodo dopo il riavvio, ma prima del giorno commitChanges. Il valore retry_counter viene diminuito quando viene chiamato questo metodo. Vengono generate le voci di log.

bool needRollback()

Determina se è necessario un rollback.

Sui dispositivi non di checkpoint, restituisce false. Sui dispositivi con checkpoint, restituisce true durante un avvio senza checkpoint.

Implementare UDC

Implementazione dei riferimenti

Per un esempio di come UDC può essere implementato, consulta dm-bow.c. Per ulteriore documentazione sulla funzione, vedi dm-bow.txt.

Configura

Nel file on fs nel file init.hardware.rc, assicurati di avere:

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

Nel file on late-fs nel file init.hardware.rc, assicurati di avere:

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

Nel file fstab.hardware, assicurati che /data sia taggato come latemount.

/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

Aggiungi partizione di metadati

L'UDC richiede una partizione di metadati per archiviare il numero di nuovi tentativi non bootloader e chiave. Configura una partizione di metadati e montala anticipatamente su /metadata.

Nel file fstab.hardware, assicurati che /metadata sia taggato come earlymount o first_stage_mount.

/dev/block/by-name/metadata           /metadata           ext4
noatime,nosuid,nodev,discard,sync
wait,formattable,first_stage_mount

Inizializza la partizione su tutti gli zeri.

Aggiungi le seguenti righe a BoardConfig.mk:

BOARD_USES_METADATA_PARTITION := true
BOARD_ROOT_EXTRA_FOLDERS := existing_folders metadata

Aggiornare i sistemi

Sistemi F2FS

Per i sistemi che utilizzano F2FS per formattare i dati, assicurati che la tua versione di F2FS supporta i checkpoint. Per ulteriori informazioni, consulta la sezione Funzionalità di checkpoint in diversi file system.

Aggiungi il flag checkpoint=fs alla sezione <fs_mgr_flags> di fstab per dispositivo montato in /data.

Sistemi non F2FS

Per i sistemi non F2FS, dm-bow deve essere abilitato nella configurazione del kernel.

Aggiungi il flag checkpoint=block alla sezione <fs_mgr_flags> di fstab per dispositivo montato in /data.

Controllare i log

Le voci di log vengono generate quando vengono chiamate le API Checkpoint.

Convalida

Per testare l'implementazione UDC, esegui l'insieme VtsKernelCheckpointTest di VTS test.