Panoramica A/B virtuale

Android ha due meccanismi di aggiornamento: aggiornamenti A/B (senza soluzione di continuità) e aggiornamenti non A/B. Per ridurre la complessità del codice e migliorare il processo di aggiornamento, in Android 11 i due meccanismi sono unificati tramite A/B virtuale per portare aggiornamenti senza interruzioni a tutti i dispositivi con un costo di archiviazione ridotto al minimo. Android 12 offre l'opzione della compressione Virtual A/B per comprimere le partizioni snapshot. Sia in Android 11 che in Android 12, si applica quanto segue:

  • Aggiornamenti virtuali A / B sono senza soluzione di continuità come gli aggiornamenti A / B. Gli aggiornamenti A/B virtuali riducono al minimo il tempo in cui un dispositivo è offline e inutilizzabile.
  • Aggiornamenti virtuali A / B possono essere annullate. Se il nuovo sistema operativo non si avvia, i dispositivi tornano automaticamente alla versione precedente.
  • Aggiornamenti virtuali A / B utilizzano un minimo di spazio in più duplicando solo le partizioni che vengono utilizzati dal bootloader. Altre partizioni aggiornabili sono snapshotted .

Contesto e terminologia

Questa sezione definisce la terminologia e descrive la tecnologia che supporta l'A/B virtuale.

Device-mapper

Device-mapper è un livello di blocco virtuale Linux utilizzato spesso in Android. Con partizioni dinamiche , partizioni come /system sono una pila di dispositivi strati:

  • In fondo alla pila è la partizione super-fisico (ad esempio, /dev/block/by-name/super ).
  • Nel mezzo è un dm-linear dispositivo, precisando che blocca in forma eccellente partizione data partizione. Ciò appare come /dev/block/mapper/system_[a|b] su un dispositivo A / B, o /dev/block/mapper/system su un dispositivo non-A / B.
  • Nella parte superiore risiede un dm-verity dispositivo, realizzato per partizioni verificati. Questo dispositivo verifica che blocca sul dm-linear dispositivo siano firmati correttamente. Si presenta come /dev/block/mapper/system-verity ed è la fonte del /system punto di montaggio.

Figura 1 mostra quello stack nell'ambito del /system mount look puntiformi simili.

Partition stacking underneath system

Figura 1. Stack sotto il / sistema di montaggio punto

dm-snapshot

Virtuale A / B si basa su dm-snapshot , un modulo device-mapper per snapshotting lo stato di un dispositivo di memorizzazione. Quando si utilizza dm-snapshot , ci sono quattro dispositivi in gioco:

  • Il dispositivo di base è il dispositivo che è snapshotted. In questa pagina, il dispositivo di base è sempre una partizione dinamica, come sistema o fornitore.
  • Il dispositivo copy-on-write (COW), per la registrazione modifiche al dispositivo base. Può essere di qualsiasi dimensione, ma deve essere abbastanza grande da accogliere tutte le modifiche al dispositivo di base.
  • Il dispositivo istantanea viene creata usando l' snapshot di destinazione. Le scritture sul dispositivo snapshot vengono scritte sul dispositivo COW. Legge dal dispositivo snapshot letta dal dispositivo base o dal dispositivo COW, a seconda che i dati a cui si accede siano stati modificati dallo snapshot.
  • Il dispositivo di origine è creata usando l' snapshot-origin bersaglio. Legge sul dispositivo di origine letto direttamente dal dispositivo di base. Scrive sul dispositivo di origine scrive direttamente sul dispositivo di base, ma viene eseguito il backup dei dati originali scrivendo sul dispositivo COW.

Device mapping for dm-snapshot

Figura 2. Dispositivo per la mappatura dm-istantanea

Istantanee compresse

In Android 12, in quanto i requisiti di spazio sul /data della partizione può essere alto, è possibile attivare gli snapshot compresso nella build per rispondere alle esigenze di spazio superiori del /data della partizione.

Le istantanee virtuali compresse A/B si basano su due nuovi componenti disponibili in Android 12:

  • dm-user , un modulo del kernel simile a FUSE che permette di implementare userspace dispositivi a blocchi.
  • snapuserd , un demone userspace per implementare un nuovo formato snapshot.

Questi componenti consentono la compressione. Le altre modifiche necessarie apportate per attuare le istantanee compressi funzionalità vengono forniti nelle sezioni successive: formato COW per istantanee compressi , dm-utente , e Snapuserd .

Formato COW per snapshot compressi

In Android 12, le istantanee compresse utilizzano un nuovo formato COW. Simile al formato integrato del kernel utilizzato per gli snapshot non compressi, il formato COW per gli snapshot compressi ha sezioni alternate di metadati e dati. Metadati del formato originale consentito solo per le operazioni di "sostituire": Sostituire blocco X l'immagine di base con il contenuto del blocco Y nell'istantanea in. Il formato COW delle istantanee compresse è più espressivo e supporta tre operazioni:

  • Copia - Blocco X nel dispositivo di base deve essere sostituito con il blocco Y nel dispositivo base.
  • Sostituire - Blocco X nel dispositivo di base dovrebbe essere sostituito con il contenuto del blocco Y nell'istantanea. Ciascuno di questi blocchi è compresso gz.
  • Zero - Blocco X nel dispositivo di base dovrebbe essere sostituito con tutti zeri.

Aggiornamenti OTA completa costituiti da sostituire e solo a zero operazioni. Aggiornamenti incrementali OTA possono inoltre avere le operazioni di copia.

dm-user in Android 12

Il modulo kernel dm-utente consente userspace per implementare dispositivi a blocchi del dispositivo-mapper. Una voce di tabella dm-utente crea un dispositivo varie sotto /dev/dm-user/<control-name> . Un userspace processo può interrogare il dispositivo per ricevere lettura e scrittura richieste del kernel. Ogni richiesta ha un buffer associato per lo spazio utente da popolare (per una lettura) o propagare (per una scrittura).

L' dm-user modulo kernel fornisce una nuova interfaccia utente visibile al kernel che non fa parte della base di codice a monte kernel.org. Fino a quando non è, Google si riserva il diritto di modificare il dm-user interfaccia Android.

Snapuserd

Lo snapuserd componente userspace al dm-user implementa virtuale A B compressione /.

Nella versione non compressa di Virtual A/B (in Android 11 e versioni precedenti o in Android 12 senza l'opzione snapshot compressa), il dispositivo COW è un file raw. Quando la compressione è attivata, le funzioni COW invece come dm-user del dispositivo, che è collegato a un'istanza del snapuserd daemon.

Il kernel non usa il nuovo formato COW. Così lo snapuserd componente traduce le richieste tra il formato COW Android e il kernel incorporato in formato:

Snapuserd component translating requests between Android COW format and kernel built-in format

Diagramma Figura 3. Flusso di snapuserd come traduttore tra Android e Kernel formati COW

Questa traduzione e decompressione non avviene mai su disco. I snapuserd componente intercetta la mucca legge e scrive che si verificano nel kernel, e strumenti utilizzando il formato COW Android.

Processi di compressione virtuale A/B

Queste sezioni forniscono dettagli sui processi utilizzati nella compressione Virtual A/B: lettura dei metadati, unione e conduzione di transizioni init.

Lettura dei metadati

Metadati è costruito da snapuserd daemon. I metadati sono principalmente una mappatura di 2 ID, 8 byte ciascuno, che rappresentano i settori da unire. In dm-snapshot si chiama come disk_exception .

struct disk_exception {
    uint64_t old_chunk;
    uint64_t new_chunk;
};

Un'eccezione del disco viene utilizzata quando un vecchio blocco di dati viene sostituito da uno nuovo.

Uno Snapuserd daemon legge il file COW interna attraverso la biblioteca mucca e costruisce i metadati per ciascuna delle operazioni COW presente nel file mucca.

I metadati legge sono iniziati dal dm-snapshot nel kernel quando la dm- snapshot viene creata dispositivo.

La figura seguente fornisce un diagramma di sequenza per il percorso IO per la costruzione dei metadati.

Sequence diagram, IO path for metadata construction

Figura 4. Sequenza di flusso per il percorso IO nella costruzione metadati

Fusione

Una volta che il processo di boot, marcature aggiornamento fessura come avvio corretto e iniziati l'unione di commutazione del dm-snapshot bersaglio al dm-snapshot-merge bersaglio.

dm-snapshot guida attraverso i metadati e avvia una stampa IO per ciascuna eccezione disco. Di seguito viene mostrata una panoramica di alto livello del percorso di I/O di unione.

Merge IO path

Figura 5. unione panoramica percorso IO

Se il dispositivo viene riavviato durante il processo di unione, l'unione riprende al riavvio successivo e l'unione è completata.

Inizia transizioni

Quando si avvia con le istantanee compressi, l'init prima fase deve iniziare snapuserd a montare le partizioni. Ciò pone un problema: quando sepolicy viene caricata e fatta rispettare, snapuserd viene messo nel contesto sbagliato, e le sue richieste di lettura non riescono, con smentite SELinux.

Per risolvere questo problema, snapuserd transizioni lock-passo con init , come segue:

  1. Prima fase di init lanci snapuserd dal ramdisk, e salva un file-descrittore aperto ad esso in una variabile d'ambiente.
  2. Prima fase di init commuta il file system root alla partizione di sistema, quindi esegue la copia sistema di init .
  3. La copia del sistema di init legge il sepolicy combinato in una stringa.
  4. Init invoca mlock() pagine su tutti i ext4-backed. Si disattiva tutti tavoli dispositivo-mapper per dispositivi istantanee, e si ferma snapuserd . Dopo questo è vietato leggere dalle partizioni, poiché ciò causa un deadlock.
  5. Utilizzando il descrittore aperto alla copia ramdisk di snapuserd , init rilancia il demone con il contesto di SELinux corretta. Le tabelle di mappatura dei dispositivi per i dispositivi snapshot vengono riattivate.
  6. Invoca init munlockall() - è sicuro di eseguire di nuovo IO.

Utilizzo dello spazio

La tabella seguente fornisce un confronto dell'utilizzo dello spazio per diversi meccanismi OTA utilizzando il sistema operativo di Pixel e le dimensioni OTA.

Impatto sulle dimensioni non-A/B A/B A/B Virtual virtuale A/B virtuale (compresso)
Immagine di fabbrica originale 4,5 GB super (immagine 3.8G + 700M riservato) 1 9GB super (3,8G + 700M riservati, per due slot) 4,5 GB super (3,8 G immagine + 700 M riservati) 4,5 GB super (3,8 G immagine + 700 M riservati)
Altre partizioni statiche /cache Nessuno Nessuno Nessuno
Archiviazione aggiuntivo durante OTA (spazio restituito dopo l'applicazione OTA) 1,4 GB su /dati 0 3.8GB 2 on / dati 2.1GB 2 on / dati
Spazio di archiviazione totale richiesto per applicare OTA 5.9GB 3 (super e dati) 9 GB (super) 8,3 GB 3 (super e dati) 6.6GB 3 (super e dati)

1 Indica il layout assunte sulla base del Pixel mapping.

2 Assume immagine nuovo sistema è la stessa dimensione dell'originale.

3 Spazio requisito è transitoria fino al riavvio.

Per implementare virtuale A / B, o per utilizzare le funzionalità di snapshot compressi, vedere Implementazione virtuale A / B