Panoramica A/B virtuale

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.
di Gemini Advanced.

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 dispositivo dm-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.

Partizione sovrapposta sotto
sistema

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.

Mappatura dei dispositivi per
Dm-snapshot

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:

Componente Snapuserd che traduce le richieste tra il formato Android COW e il kernel
integrato
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.

Diagramma di sequenza, percorso IO per i metadati
lavori

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.

Unisci percorso IO

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:

  1. Il framework monta la partizione /system da un dispositivo dm-verity, che è posizionato sopra un dispositivo dm-user. Ciò significa che ogni I/O dal file system radice viene indirizzato a dm-user.
  2. dm-user instrada l'I/O al daemon snapuserd dello spazio utente, che gestisce la richiesta di I/O.
  3. Al termine dell'operazione di unione, il framework comprime dm-verity in alto di dm-linear (system_base) e rimuove dm-user.

Compressione A/B virtuale
di elaborazione

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:

  1. La prima fase init avvia snapuserd dal ramdisk e salva una file-descriptor in una variabile di ambiente.
  2. La prima fase init esegue il passaggio del file system radice alla partizione di sistema, quindi esegue la copia di sistema di init.
  3. La copia di sistema di init legge il sepolicy combinato in una stringa.
  4. Init richiama mlock() su tutte le pagine supportate da ext4. Quindi disattiva tutti le tabelle device-mapper per i dispositivi snapshot e interrompe snapuserd. Dopo questa data è vietato leggere dalle partizioni, poiché ciò causa un deadlock.
  5. 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.
  6. 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