Android ha due meccanismi di aggiornamento: gli aggiornamenti A/B (senza interruzioni) e gli aggiornamenti non A/B. Per ridurre la complessità del codice e migliorare il processo di aggiornamento, in Android 11 due meccanismi sono unificati tramite A/B virtuale per portare con costi di archiviazione ridotti al minimo. Android 12 offre l'opzione della compressione A/B virtuale per comprimere le partizioni di snapshot. Sia in Android 11 che in Android 12, quanto segue applica:
- Gli aggiornamenti A/B virtuali sono senza interruzioni come gli aggiornamenti A/B. Aggiornamenti A/B virtuali ridurre al minimo il tempo in cui un dispositivo è offline e inutilizzabile.
- Gli aggiornamenti A/B virtuali possono essere ripristinati. Se il nuovo sistema operativo non si avvia, il rollback automatico alla versione precedente.
- Gli aggiornamenti A/B virtuali utilizzano un minimo di spazio extra duplicando solo utilizzate dal bootloader. Altre partizioni aggiornabili sono istantanea.
Background e terminologia
Questa sezione definisce la terminologia e descrive la tecnologia che supporta A/B virtuale.
Mappatore dispositivi
Device-mapper è un livello di blocco virtuale Linux usato spesso in Android. Con
partizioni dinamiche, partizioni come
/system
sono uno stack di dispositivi su più livelli:
- In fondo allo stack c'è la partizione super fisica (ad esempio,
/dev/block/by-name/super
). - Al centro c'è un dispositivo
dm-linear
, che specifica quali blocchi nella la partizione specificata. Questo viene visualizzato come/dev/block/mapper/system_[a|b]
su un dispositivo A/B oppure/dev/block/mapper/system
su un dispositivo non A/B. - In alto si trova un dispositivo
dm-verity
, creato per le partizioni verificate. Questo dispositivo verifica che i blocchi sul dispositivodm-linear
siano firmati in modo corretto. Viene visualizzato come/dev/block/mapper/system-verity
ed è l'origine del punto di montaggio/system
.
La figura 1 mostra l'aspetto della pila sotto il punto di montaggio /system
.
Figura 1. Impila lo stack nel punto di montaggio /system
Dm-snapshot
A/B virtuale si basa su dm-snapshot
, un modulo di mappatura dei dispositivi per creare uno snapshot del
di un dispositivo di archiviazione. Quando usi dm-snapshot
, ci sono quattro dispositivi in
metti:
- Il dispositivo di base è il dispositivo di cui viene eseguito lo snapshot. In questa pagina, la base dispositivo è sempre una partizione dinamica, come il sistema o il fornitore.
- Il dispositivo copy-on-write (COW), per la registrazione delle modifiche al dispositivo di base. it può essere di qualsiasi dimensione, ma deve essere abbastanza grande da poter contenere tutte le modifiche dispositivo di base.
- Il dispositivo snapshot viene creato utilizzando il target
snapshot
. Scrive al vengono scritti al dispositivo COW. Legge dallo snapshot di lettura dal dispositivo di base o dal dispositivo COW, a seconda se i dati a cui si accede sono stati modificati dallo snapshot. - Il dispositivo origin viene creato utilizzando la destinazione
snapshot-origin
. Letture in il dispositivo di origine legge direttamente dal dispositivo di base. Scrive all'origine il dispositivo scrive direttamente sul dispositivo base, ma viene eseguito il backup dei dati originali scrivendo al dispositivo COW.
Figura 2. Mappatura dei dispositivi per Dm-snapshot
Snapshot compressi
In Android 12 e versioni successive, a causa dei requisiti di spazio
la partizione /data
può essere alta, puoi abilitare gli snapshot compressi
per soddisfare i requisiti di spazio più elevati della partizione /data
.
Gli snapshot virtuali compressi A/B sono basati sui seguenti componenti disponibili su Android 12 e versioni successive:
dm-user
, un modulo kernel simile a FUSE che consente lo spazio utente per implementare i dispositivi a blocchi.snapuserd
, un daemon dello spazio utente per implementare un nuovo snapshot formato.
Questi componenti consentono la compressione. Le altre modifiche necessarie apportate le funzionalità degli snapshot compressi sono illustrate nelle sezioni successive: Formato COW per snapshot compressi, dm-user e Snapuserd.
Formato COW per snapshot compressi
In Android 12 e versioni successive, gli snapshot compressi utilizzano un formato COW. Simile al formato integrato del kernel usato per i file non compressi il formato COW per gli snapshot compressi ha sezioni alternate di metadati e dati. I metadati del formato originale sono consentiti solo per l'opzione replace operazioni: sostituisci il blocco X nell'immagine di base con il contenuto del blocco Y nell'istantanea. Il formato COW degli snapshot compressi è più espressivo supporta le seguenti operazioni:
- Testo: il blocco X nel dispositivo di base deve essere sostituito con il blocco Y in il dispositivo di base.
- Sostituisci: il blocco X nel dispositivo di base deve essere sostituito con i contenuti. del blocco Y nell'istantanea. Ciascuno di questi blocchi è compresso con gz.
- Zero: il blocco X nel dispositivo di base deve essere sostituito con tutti gli zeri.
- XOR: il dispositivo COW memorizza byte compressi XOR tra il blocco X e Blocca Y. (disponibile su Android 13 e versioni successive.)
Gli aggiornamenti OTA completi consistono solo in operazioni di sostituzione e zero. Incrementale Gli aggiornamenti OTA possono includere anche operazioni di copia.
dm-user in Android 12
Il modulo kernel dm-user consente a userspace
di implementare il blocco device-mapper
dispositivi mobili. Una voce nella tabella utente dm crea un dispositivo vari in
/dev/dm-user/<control-name>
. Un processo userspace
può eseguire il polling del dispositivo per
ricevono richieste di lettura e scrittura dal kernel. A ogni richiesta è associato
buffer per lo spazio utente da compilare (per una lettura) o propagarsi (per una scrittura).
Il modulo del kernel dm-user
fornisce una nuova interfaccia visibile all'utente al kernel
che non fa parte del codebase upstream kernel.org. Finché non lo sarà, Google
si riserva il diritto di modificare l'interfaccia di dm-user
in Android.
Snapuserd
Il componente dello spazio utente snapuserd
per dm-user
implementa A/B virtuale
compressione.
Nella versione non compressa di Virtual A/B (in Android 11 e versioni precedenti oppure
in Android 12 senza l'opzione istantanea compressa).
il dispositivo COW è un file RAW. Quando la compressione è abilitata, la funzione COW
come dispositivo dm-user
, connesso a un'istanza
snapuserd
daemon.
Il kernel non usa il nuovo formato COW. Quindi il componente snapuserd
traduce le richieste tra il formato Android COW e la memoria integrata
formato:
Figura 3. Diagramma di flusso di Snapuserd come traduttore tra Android e Kernel Formati COW
Questa traslazione e decompressione non avvengono mai su disco. snapuserd
intercetta le letture e scritture COW che avvengono nel kernel, e
utilizzando il formato Android COW.
Compressione XOR
Per i dispositivi che verranno lanciati con Android 13 e versioni successive, La funzionalità di compressione XOR, abilitata per impostazione predefinita, abilita lo spazio utente snapshot per archiviare byte compressi XOR tra blocchi vecchi e nuovi. Quando vengono modificati solo pochi byte in un blocco in un aggiornamento A/B virtuale, lo schema di archiviazione a compressione utilizza meno spazio rispetto a quello predefinito poiché gli snapshot non memorizzano i 4000 byte completi. La riduzione delle dimensioni dello snapshot è possibile perché i dati XOR contengono molti zeri ed sono più facili da comprimere rispetto ai dati non elaborati bloccare i dati. Sui dispositivi Pixel, la compressione XOR riduce le dimensioni delle istantanee del 25% per il 40%.
Per i dispositivi che eseguono l'upgrade ad Android 13 e versioni successive, XOR la compressione deve essere abilitata. Per maggiori dettagli, vedi XOR compressa.
Processi di compressione A/B virtuali
Questa sezione fornisce dettagli sul processo di compressione A/B virtuale utilizzato in Android 13 e Android 12.
Lettura dei metadati (Android 12)
I metadati vengono creati da un daemon snapuserd
. I metadati sono principalmente
mappatura di due ID da 8 byte ciascuno, che rappresentano i settori da unire.
In dm-snapshot
si chiama disk_exception
.
struct disk_exception {
uint64_t old_chunk;
uint64_t new_chunk;
};
Viene utilizzata un'eccezione del disco quando un vecchio blocco di dati viene sostituito con uno nuovo.
Un daemon snapuserd
legge il file COW interno tramite la libreria COW e
crea i metadati per ciascuna delle operazioni COW presenti nel file COW.
Le letture dei metadati vengono avviate da dm-snapshot
nel kernel quando viene creato il dispositivo dm-
snapshot
.
La figura seguente fornisce un diagramma di sequenza per il percorso di I/O per i metadati edilizia.
Figura 4. Flusso di sequenza per il percorso di I/O nella creazione dei metadati
Unione (Android 12)
Una volta completato il processo di avvio, il motore di aggiornamento contrassegna lo slot come avvio
riuscito e avvia l'unione trasferendo il target dm-snapshot
al
Obiettivo dm-snapshot-merge
.
dm-snapshot
esamina i metadati e avvia un IO di unione per ciascun disco
. Di seguito è riportata una panoramica generale del percorso dell'ordine di inserzione di unione.
Figura 5. Panoramica del percorso di IO di unione
Se il dispositivo viene riavviato durante il processo di unione, l'unione riprende nella riavviate e l'unione sarà completata.
Livelli di mappatura dei dispositivi
Per i dispositivi che verranno lanciati con Android 13 e versioni successive,
i processi di unione degli snapshot e degli snapshot nella compressione A/B virtuale
dal componente dello spazio utente snapuserd
. Per i dispositivi che eseguono l'upgrade ad Android
13 e successive, questa funzionalità deve essere attivata. Per
vedi Spazio utente
unisci.
Di seguito viene descritto il processo di compressione A/B virtuale:
- Il framework monta la partizione
/system
da un dispositivodm-verity
, che è posizionato sopra un dispositivodm-user
. Ciò significa che ogni I/O dal file system radice viene indirizzato adm-user
. dm-user
instrada l'I/O al daemonsnapuserd
dello spazio utente, che gestisce la richiesta di I/O.- Al termine dell'operazione di unione, il framework comprime
dm-verity
in alto didm-linear
(system_base
) e rimuovedm-user
.
Figura 6. Processo di compressione A/B virtuale
Il processo di unione degli snapshot può essere interrotto. Se il dispositivo viene riavviato durante il processo di unione riprende dopo il riavvio.
Transizioni di inizializzazione
Durante l'avvio con snapshot compressi, l'init di prima fase deve iniziare
snapuserd
per montare le partizioni. Questo presenta un problema: quando viene caricato sepolicy
e applicata, snapuserd
viene inserita nel contesto sbagliato e le sue richieste di lettura
con gli attacchi selinux.
Per risolvere questo problema, snapuserd
esegue le transizioni in fase di blocco con init
, come segue:
- La prima fase
init
avviasnapuserd
dal ramdisk e salva una file-descriptor in una variabile di ambiente. - La prima fase
init
esegue il passaggio del file system radice alla partizione di sistema, quindi esegue la copia di sistema diinit
. - La copia di sistema di
init
legge il sepolicy combinato in una stringa. Init
richiamamlock()
su tutte le pagine supportate da ext4. Quindi disattiva tutti le tabelle device-mapper per i dispositivi snapshot e interrompesnapuserd
. Dopo questa data è vietato leggere dalle partizioni, poiché ciò causa un deadlock.- Utilizzo del descrittore aperto della copia ramdisk di
snapuserd
,init
riavvia il daemon con il contesto Selinux corretto. Tabelle di mappatura dei dispositivi per i dispositivi snapshot. - L'inizializzazione richiama
munlockall()
: puoi eseguire di nuovo l'IO.
Utilizzo dello spazio
La tabella seguente mette a confronto l'utilizzo dello spazio per diverse OTA in base alle dimensioni del sistema operativo e delle OTA di Pixel.
Impatto sulle dimensioni | non A/B | A/B | A/B virtuale | A/B virtuale (compresso) |
---|---|---|---|---|
Immagine originale del produttore | 4,5 GB super (immagine 3,8 GB + 700 MB riservati)1 | 9 GB super (3,8 G + 700 M riservati, per due slot) | 4,5 GB super (immagine 3,8 GB + 700 M riservati) | 4,5 GB super (immagine 3,8 GB + 700 M riservati) |
Altre partizioni statiche | /cache | Nessuno | Nessuno | Nessuno |
Spazio di archiviazione aggiuntivo durante l'OTA (spazio restituito dopo l'applicazione dell'OTA) | 1,4 GB su /data | 0 | 3,8 GB2 su /data | 2,1 GB2 su /data |
Spazio di archiviazione totale necessario per applicare l'aggiornamento OTA | 5,9 GB3 (super e dati) | 9GB (super) | 8,3 GB3 (super e dati) | 6,6 GB3 (super e dati) |
1 Indica il layout presunto in base alla mappatura di Pixel.
2 Partendo dal presupposto che la nuova immagine di sistema sia delle stesse dimensioni dell'originale.
3 Il requisito di spazio è temporaneo fino al riavvio.
Per implementare A/B virtuale o per utilizzare funzionalità di snapshot compressi, consulta Implementazione di A/B virtuale