Présentation des tests A/B virtuels

Le déploiement A/B virtuel est le principal mécanisme de mise à jour d'Android. Les versions A/B virtuelles s'appuient sur les anciennes mises à jour A/B (voir Mises à jour système A/B) et les versions non A/B, qui sont obsolètes dans la version 15 afin de réduire l'espace supplémentaire requis par les mises à jour.

Le test A/B virtuel ne dispose pas d'emplacement supplémentaire pour les partitions dynamiques. Consultez la section Partitions dynamiques. Au lieu de cela, le delta est écrit dans un instantané, puis fusionné dans la partition de base après confirmation du démarrage. Le test A/B virtuel utilise un format d'instantané spécifique à Android. Consultez la section Format COW pour les instantanés compressés, qui permet de compresser les instantanés et de réduire l'espace disque utilisé. Dans une mise à jour OTA complète, la taille de l'instantané est réduite d'environ 45% avec la compression, et la taille de l'instantané OTA incrémentielle est réduite d'environ 55%.

Android 12 offre la possibilité de compression A/B virtuelle pour compresser les partitions créées à partir d'instantanés. Le test A/B virtuel offre les avantages suivants :

  • Les mises à jour A/B virtuelles sont fluides (la mise à jour se produit entièrement en arrière-plan lorsque l'appareil est opérationnel), comme les mises à jour A/B. Les mises à jour A/B virtuelles réduisent le temps pendant lequel un appareil est hors connexion et inutilisable.
  • Les mises à jour A/B virtuelles peuvent être annulées. Si le nouveau système d'exploitation ne démarre pas, les appareils reviennent automatiquement à la version précédente.
  • Les mises à jour A/B virtuelles utilisent un espace supplémentaire minimal en dupliquant uniquement les partitions utilisées par le bootloader. Les autres partitions pouvant être mises à jour sont mises en cache.

Contexte et terminologie

Cette section définit la terminologie et décrit la technologie compatible avec les tests A/B virtuels. Lors de l'installation OTA, les nouvelles données du système d'exploitation sont écrites dans son nouvel emplacement pour les partitions physiques ou dans un appareil COW spécifique à Android. Après le redémarrage de l'appareil, les données de partition dynamique sont fusionnées dans son appareil de base à l'aide du démon dm-user et du démon snapuserd. Ce processus se déroule entièrement dans l'espace utilisateur.

Device-mapper

Device-mapper est une couche de blocs virtuels Linux souvent utilisée dans Android. Avec les partitions dynamiques, les partitions telles que /system sont une pile d'appareils en couches:

  • La partition super physique (par exemple, /dev/block/by-name/super) se trouve en bas de la pile.
  • Au milieu se trouve un appareil dm-linear, qui spécifie les blocs de la superpartition qui constituent la partition dynamique donnée. Il s'affiche sous la forme /dev/block/mapper/system_[a|b] sur un appareil A/B ou /dev/block/mapper/system sur un appareil non A/B.
  • En haut se trouve un appareil dm-verity, créé pour les partitions validées. Cet appareil vérifie que les blocs de l'appareil dm-linear sont correctement signés. Il s'affiche sous la forme /dev/block/mapper/system-verity et constitue la source du point d'installation /system.

La figure 1 montre à quoi ressemble la pile sous le point d'installation /system.

Empilement de partitions sous le système

Figure 1 : Pile sous le point d'installation /system

Instantanés compressés

Dans Android 12 et versions ultérieures, les exigences en termes d'espace sur la partition /data pouvant être élevées, vous pouvez activer les instantanés compressés dans votre build pour répondre aux exigences d'espace plus élevées de la partition /data.

Les instantanés compressés A/B virtuels sont basés sur les composants suivants, disponibles dans Android 12 et versions ultérieures:

  • dm-user, un module de noyau semblable à FUSE qui permet à l'espace utilisateur d'implémenter des périphériques de bloc.
  • snapuserd, un démon d'espace utilisateur pour implémenter un nouveau format d'instantané.

Ces composants permettent la compression. Les autres modifications nécessaires apportées pour implémenter les fonctionnalités d'instantanés compressés sont décrites dans les sections suivantes : Format COW pour les instantanés compressés, dm-user et snapuserd.

Format COW pour les instantanés compressés

Sous Android 12 et versions ultérieures, les instantanés compressés utilisent un format COW spécifique à Android. Le format COW contient des métadonnées sur l'OTA et dispose de tampons distincts contenant des opérations COW et de nouvelles données du système d'exploitation. Par rapport au format d'instantané du kernel, qui n'autorisait que les opérations de remplacement (remplacement du bloc X dans l'image de base par le contenu du bloc Y dans l'instantané), le format COW des instantanés compressés Android est plus expressif et prend en charge les opérations suivantes:

  • Copie: le bloc X de l'appareil de base doit être remplacé par le bloc Y de l'appareil de base.
  • Remplacement: le bloc X de l'appareil de base doit être remplacé par le contenu du bloc Y de l'instantané. Chacun de ces blocs est compressé gz.
  • Zéro: le bloc X de l'appareil de base doit être remplacé par des zéros.
  • XOR: l'appareil COW stocke les octets compressés XOR entre le bloc X et le bloc Y. (disponible sur Android 13 ou version ultérieure).

Les mises à jour OTA complètes ne comprennent que des opérations remplace et zéro. Les mises à jour OTA incrémentielles peuvent également comporter des opérations de copie.

La mise en page complète de l'instantané sur le disque se présente comme suit:

format vache

Figure 2. Format Android COW sur le disque

dm-user

Le module du noyau dm-user permet à userspace d'implémenter des périphériques de mappage d'appareils. Une entrée de table dm-user crée un appareil divers sous /dev/dm-user/<control-name>. Un processus userspace peut interroger l'appareil pour recevoir des requêtes de lecture et d'écriture du noyau. Chaque requête est associée à un tampon que l'espace utilisateur doit remplir (pour une lecture) ou propager (pour une écriture).

Le module du kernel dm-user fournit une nouvelle interface visible par l'utilisateur du kernel qui ne fait pas partie de la base de code kernel.org en amont. En attendant, Google se réserve le droit de modifier l'interface dm-user dans Android.

snapuserd

Le composant de l'espace utilisateur snapuserd de dm-user implémente la compression A/B virtuelle. Snapuserd est un démon d'espace utilisateur chargé d'écrire et de lire les appareils Android COW. Toutes les E/S vers l'instantané doivent passer par ce service. Lors de l'installation OTA, de nouvelles données du système d'exploitation sont écrites dans l'instantané par snapuserd (avec compression). L'analyse des métadonnées et la décompression des données des nouveaux blocs sont également gérées ici.

Compression XOR

Pour les appareils lancés avec Android 13 ou version ultérieure, la fonctionnalité de compression XOR, qui est activée par défaut, permet aux instantanés de l'espace utilisateur de stocker des octets compressés XOR entre les anciens blocs et les nouveaux blocs. Lorsque seuls quelques octets d'un bloc sont modifiés lors d'une mise à jour A/B virtuelle, le schéma de stockage de compression XOR utilise moins d'espace que le schéma de stockage par défaut, car les instantanés ne stockent pas la totalité des 4 Ko. Cette réduction de la taille de l'instantané est possible, car les données XOR contiennent de nombreux zéros et sont plus faciles à compresser que les données de blocs brutes. Sur les appareils Pixel, la compression XOR réduit la taille des instantanés de 25% à 40%.

Pour les appareils qui passent à Android 13 ou version ultérieure, la compression XOR doit être activée. Pour en savoir plus, consultez la section Compression XOR.

Fusion d'instantanés

Pour les appareils lancés avec Android 13 ou version ultérieure, les processus d'instantané et de fusion d'instantanés dans la compression A/B virtuelle sont effectués par le composant d'espace utilisateur snapuserd. Pour les appareils qui passent à Android 13 ou version ultérieure, cette fonctionnalité doit être activée. Pour en savoir plus, consultez la section Fusion de l'espace utilisateur.

Voici une description du processus de compression A/B virtuelle:

  1. Le framework installe la partition /system à partir d'un appareil dm-verity, qui est empilée sur un appareil dm-user. Cela signifie que chaque E/S du système de fichiers racine est acheminée vers dm-user.
  2. dm-user achemine les E/S vers le daemon snapuserd de l'espace utilisateur, qui gère la requête d'E/S.
  3. Une fois l'opération de fusion terminée, le framework réduit dm-verity au-dessus de dm-linear (system_base) et supprime dm-user.

Processus de compression A/B virtuel

Figure 3. Processus de compression A/B virtuel

Le processus de fusion des instantanés peut être interrompu. Si l'appareil est redémarré pendant le processus de fusion, le processus de fusion reprend après le redémarrage.

Transitions d'initialisation

Lors du démarrage avec des instantanés compressés, l'initialisation de premier niveau doit démarrer snapuserd pour monter les partitions. Cela pose un problème: lorsque sepolicy est chargé et appliqué, snapuserd est placé dans le mauvais contexte, et ses requêtes de lecture échouent, avec des refus selinux.

Pour résoudre ce problème, snapuserd effectue une transition en parallèle avec init, comme suit:

  1. init de premier niveau lance snapuserd à partir du ramdisk et y enregistre un descripteur de fichier ouvert dans une variable d'environnement.
  2. init de premier niveau bascule le système de fichiers racine vers la partition système, puis exécute la copie système de init.
  3. La copie système de init lit la politique de sécurité combinée dans une chaîne.
  4. Init appelle mlock() sur toutes les pages basées sur ext4. Il désactive ensuite toutes les tables de mappage d'appareils pour les appareils d'instantanés et arrête snapuserd. Après cela, il est interdit de lire à partir de partitions, car cela entraîne un interblocage.
  5. À l'aide du descripteur ouvert pour la copie de ramdisk de snapuserd, init relance le daemon avec le contexte selinux approprié. Les tables de mappage d'appareils pour les appareils d'instantanés sont réactivées.
  6. Init appelle munlockall(). Vous pouvez à nouveau effectuer des E/S en toute sécurité.

Utilisation de l'espace

Le tableau suivant compare l'espace utilisé par différents mécanismes OTA à l'aide des tailles de l'OS et des OTA du Pixel.

Impact sur la taille non-A/B A/B Test A/B virtuel Test A/B virtuel (compressé)
Image d'usine d'origine Super 4,5 Go (image 3,8 Go + 700 Mo réservés)1 9 Go super (3,8 Go + 700 Mo réservés, pour deux emplacements) Super 4,5 Go (image 3,8 Go + 700 Mo réservés) Super 4,5 Go (image 3,8 Go + 700 Mo réservés)
Autres partitions statiques /cache Aucune Aucun Aucune
Espace de stockage supplémentaire lors de la mise à jour OTA (espace renvoyé après l'application de la mise à jour OTA) 1,4 Go sur /data 0 3,8 Go2 sur /data 2,1 Go2 sur /data
Espace de stockage total requis pour appliquer la mise à jour OTA 5,9 Go3 (super et données) 9 Go (super) 8,3 Go3 (super et données) 6,6 Go3 (super et données)

1 Indique la mise en page supposée basée sur le mappage de pixels.

2Suppose que la nouvelle image système est de la même taille que l'image d'origine.

3 L'espace requis est temporaire jusqu'au redémarrage.

Android 11 Virtual A/B

Android 11 de Virtual A/B a écrit dans la partition dynamique à l'aide du format COW du noyau. Ce mode a finalement été abandonné, car le format COW du kernel n'est pas compatible avec la compression.

Version A/B virtuelle Android 12

Sous Android 12, la compression est prise en charge sous la forme d'un format COW spécifique à Android. Cette version de Virtual A/B nécessitait une traduction de la COW spécifique à Android au format COW du kernel. Ce processus a finalement été remplacé dans Android 13, qui a supprimé la dépendance au format COW du noyau et également dm-snapshot.

Pour implémenter le test A/B virtuel ou utiliser les fonctionnalités d'instantanés compressés, consultez la section Implémenter le test A/B virtuel.