Punto di controllo dei dati dell'utente

Android 10 introduce User Data Checkpoint (UDC), che consente ad Android di tornare allo stato precedente quando un aggiornamento Android over-the-air (OTA) fallisce. Con UDC, se un aggiornamento Android OTA fallisce, il dispositivo può tornare in sicurezza allo stato precedente. Sebbene gli aggiornamenti A/B risolvano questo problema per l'avvio anticipato, il rollback non è supportato quando la partizione dei dati dell'utente (montata su /data ) viene modificata.

L'UDC consente al dispositivo di ripristinare la partizione dei dati utente anche dopo essere stata modificata. La funzionalità UDC ottiene questo risultato con funzionalità di checkpoint nel file system, un'implementazione alternativa quando il file system non supporta i checkpoint, l'integrazione con il meccanismo A/B del bootloader supportando anche aggiornamenti non A/B e il supporto per l'associazione della versione chiave e prevenzione del rollback chiave.

Impatto sull'utente

La funzionalità UDC migliora l'esperienza di aggiornamento OTA per gli utenti poiché meno utenti perdono i propri dati quando un aggiornamento OTA fallisce. Ciò può ridurre il numero di chiamate di supporto da parte degli utenti che riscontrano problemi durante il processo di aggiornamento. Tuttavia, quando un aggiornamento OTA fallisce, gli utenti potrebbero notare il riavvio del dispositivo più volte.

Come funziona

Funzionalità checkpoint in diversi file system

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

Per altri file system, UDC utilizza un dispositivo virtuale di mappatura dispositivi chiamato dm_bow per la funzionalità checkpoint. dm_bow si trova tra il dispositivo e il file system. Quando una partizione viene montata, viene emesso un trim che fa sì che il file system emetta comandi di trim su tutti i blocchi liberi. dm_bow intercetta questi ritagli e li usa per impostare un elenco di blocchi gratuiti. Le letture e le scritture vengono quindi inviate al dispositivo senza modifiche, ma prima che venga consentita la scrittura, viene eseguito il backup dei dati necessari per un ripristino su 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 qualsiasi checkpoint corrente. init chiama quindi la funzione needsCheckpoint per determinare se il dispositivo è in uno stato A/B del bootloader o ha impostato il conteggio dei tentativi di aggiornamento. Se una delle due è vera, Android chiama createCheckpoint per aggiungere flag di montaggio o creare un dispositivo dm_bow .

Dopo aver montato la partizione, viene richiamato il codice del checkpoint per eseguire i trim. Il processo di avvio continua quindi normalmente. A LOCKED_BOOT_COMPLETE , Android chiama commitCheckpoint per confermare il checkpoint corrente e l'aggiornamento continua normalmente.

Gestisci le chiavi principali

Le chiavi principali vengono utilizzate per la crittografia del dispositivo o per altri scopi. Per gestire queste chiavi, Android ritarda le chiamate di eliminazione delle chiavi fino al completamento del checkpoint.

Monitorare la salute

Un demone di integrità verifica che ci sia spazio su disco sufficiente per creare un checkpoint. Il demone dell'integrità si trova in cp_healthDaemon in Checkpoint.cpp .

Il demone 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 demone di integrità.
  • ro.sys.cp_commit_on_full : controlla se il demone di integrità riavvia il dispositivo o esegue il commit del checkpoint e continua quando il disco è pieno.

API del punto di controllo

Le API Checkpoint vengono utilizzate dalla funzionalità UDC. Per altre API utilizzate dall'UDC, vedere IVold.aidl .

void startCheckpoint(int nuovo tentativo)

Crea un punto di controllo.

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

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

void commitChanges()

Effettua il commit delle modifiche.

Il framework chiama questo metodo dopo il riavvio quando le modifiche sono pronte per essere applicate. Questo viene chiamato prima che i dati (come immagini, video, SMS, ricevuta del server) vengano scritti nei dati utente e prima BootComplete .

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

abortChanges()

Forza il riavvio e ripristina il checkpoint. Abbandona tutte le modifiche ai dati utente dal primo riavvio.

Il framework chiama questo metodo dopo il riavvio ma prima di commitChanges . retry_counter viene diminuito quando viene chiamato questo metodo. Vengono generate le voci di registro.

bool necessita di Rollback()

Determina se è necessario un rollback.

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

Implementare l'UDC

Implementazione di riferimento

Per un esempio di come può essere implementato l'UDC, vedere dm-bow.c . Per ulteriore documentazione sulla funzionalità, vedere dm-bow.txt .

Impostare

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

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

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

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

Nel tuo file fstab.hardware , assicurati che /data sia contrassegnato 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 tentativi e le chiavi non del bootloader. Configura una partizione di metadati e montala in anticipo su /metadata .

Nel file fstab.hardware , assicurati che /metadata sia contrassegnato 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 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 supporti i checkpoint. Per ulteriori informazioni, consulta Funzionalità checkpoint in diversi file system .

Aggiungi il flag checkpoint=fs alla sezione <fs_mgr_flags> di fstab per il 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 il dispositivo montato in /data .

Controlla i log

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

Validazione

Per testare l'implementazione dell'UDC, esegui il set di test VTS VtsKernelCheckpointTest .