Implémenter des tests A/B virtuels

Pour implémenter des tests A/B virtuels sur un nouvel appareil ou pour adapter un appareil déjà lancé, vous devez doit modifier le code spécifique à l'appareil.

Indicateurs de compilation

Les appareils qui utilisent des tests A/B virtuels doivent être configurés en tant que tests A/B appareil et doivent être lancés avec dynamique partitions.

Configurez les appareils lancés avec une fonctionnalité A/B virtuelle pour qu'ils héritent de la configuration configuration de base de l'appareil:

$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota.mk)

Les appareils lancés avec des tests A/B virtuels n'ont besoin que de moitié moins de cartes pour BOARD_SUPER_PARTITION_SIZE, car les emplacements B ne sont plus en super. En d'autres termes, La valeur de BOARD_SUPER_PARTITION_SIZE doit être supérieure ou égale à somme(taille des groupes de mise à jour) + frais généraux, qui, à leur tour, doivent être supérieurs ou égal à somme(taille des partitions) + surcharge.

Pour Android 13 ou version ultérieure, pour activer la compression avec des tests A/B virtuels, héritent de la configuration de base suivante:

$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota/android_t_baseline.mk)

Cela permet d'obtenir des instantanés de l'espace utilisateur avec des tests A/B virtuels tout en utilisant un nœud sans opération de compression. Vous pouvez ensuite configurer la méthode de compression sur l'une des méthodes compatibles, gz, zstd et lz4.

PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := lz4

Pour Android 12, pour activer les instantanés compressés avec Virtual A/B, héritez de la configuration de base suivante:

$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota/compression.mk)

Compression XOR

Pour les appareils passant à Android 13 ou version ultérieure, le La fonctionnalité de compression XOR n'est pas est activée par défaut. Pour activer la compression XOR, ajoutez le code suivant au fichier .mk.

PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true

La compression XOR est activée par défaut pour les appareils qui héritent android_t_baseline.mk

Fusion d'espaces utilisateur

Pour les appareils passant à Android 13 ou version ultérieure, le processus de fusion des espaces utilisateur comme décrit dans Device-mapper la superposition de couches n'est pas activée par défaut. Pour activer la fusion de l'espace utilisateur, ajoutez la ligne suivante au fichier .mk de l'appareil :

PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true

La fusion des espaces utilisateur est activée par défaut sur les appareils lancés avec 13 et ultérieure.

Contrôle du démarrage HAL

Le contrôle de démarrage CARL fournit une interface permettant aux clients OTA de contrôler les emplacements de démarrage. Tests A/B virtuels nécessite une mise à niveau mineure du HAL de contrôle de démarrage, car des API supplémentaires sont nécessaires pour garantir que le bootloader est protégé pendant le flash ou le rétablissement de la configuration d'usine. Voir IBootControl.hal et types.hal pour obtenir la dernière version de la définition HAL.

// hardware/interfaces/boot/1.1/types.hal
enum MergeStatus : uint8_t {
    NONE, UNKNOWN, SNAPSHOTTED, MERGING, CANCELLED };

// hardware/interfaces/boot/1.1/IBootControl.hal
package android.hardware.boot@1.1;
interface IBootControl extends @1.0::IBootControl {
    setSnapshotMergeStatus(MergeStatus status)
        generates (bool success);
    getSnapshotMergeStatus()
        generates (MergeStatus status);
}
// Recommended implementation

Return<bool> BootControl::setSnapshotMergeStatus(MergeStatus v) {
    // Write value to persistent storage
    // e.g. misc partition (using libbootloader_message)
    // bootloader rejects wipe when status is SNAPSHOTTED
    // or MERGING
}

Modifications fstab

L'intégrité de la partition de métadonnées est essentielle au processus de démarrage, en particulier juste après l'application d'une mise à jour OTA. Ainsi, la partition de métadonnées doit vérifier avant que first_stage_init ne l'installe. Pour ce faire, ajoutez le paramètre check fs_mgr à l'entrée de /metadata. Vous trouverez ci-dessous Exemple:

/dev/block/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard,sync wait,formattable,first_stage_mount,check

Exigences du noyau

Pour activer la création d'instantanés, définissez CONFIG_DM_SNAPSHOT sur true.

Pour les appareils utilisant F2FS, incluez l'indicateur f2fs: export FS_NOCOW_FL vers user du correctif du noyau pour corriger l'épinglage de fichiers. Incluez les éléments f2fs: support alignés épinglés fichier du noyau.

L'A/B virtuelle repose sur des fonctionnalités ajoutées dans la version 4.3 du noyau: le overflow bit d'état dans les cibles snapshot et snapshot-merge. Lancement pour tous les appareils équipés d'Android 9 ou version ultérieure doivent déjà disposer de la version 4.4 ou ultérieure du noyau.

Pour activer les instantanés compressés, la version de noyau minimale compatible est 4.19. Définissez CONFIG_DM_USER=m ou CONFIG_DM_USER=y. Si vous utilisez l'ancien (un module), le module doit être chargé dans le ramdisk de première étape. Pour ce faire, vous pouvez en ajoutant la ligne suivante au Makefile de l'appareil:

BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko

Retrofit sur les appareils passant à Android 11

Lors de la mise à niveau vers Android 11, les appareils lancés avec des partitions dynamiques peuvent des tests A/B virtuels si vous le souhaitez. Le processus de mise à jour est essentiellement le même que pour appareils lancés avec des tests A/B virtuels, à quelques différences mineures:

  • Emplacement des fichiers COW : pour les appareils de lancement, le client OTA utilise tout l'espace vide disponible dans la super-partition avant d'utiliser l'espace dans /data Pour les appareils rétrofit, il y a toujours suffisamment de place dans le afin que le fichier COW ne soit jamais créé sur /data.

  • Indicateurs de fonctionnalités lors de la compilation : pour les appareils qui adaptent les tests A/B virtuels, PRODUCT_VIRTUAL_AB_OTA et PRODUCT_VIRTUAL_AB_OTA_RETROFIT sont tous les deux définis à true, comme indiqué ci-dessous:

    (call inherit-product, \
      (SRC_TARGET_DIR)/product/virtual_ab_ota_retrofit.mk)
    
  • Taille de la partition supérieure : les appareils équipés d'un A/B virtuel peuvent réduire BOARD_SUPER_PARTITION_SIZE en deux, car les emplacements B ne se trouvent pas dans le partition. Les appareils qui modernisent les tests A/B virtuels conservent l'ancienne super partition taille, donc BOARD_SUPER_PARTITION_SIZE est supérieur ou égal à 2 * sum(taille des groupes de mise à jour) + sur site, qui à son tour est supérieur ou égal à 2 * somme(taille des partitions) + frais généraux.

Modifications apportées au bootloader

Lors de l'étape de fusion d'une mise à jour, /data contient la seule instance entière de OS Android. Une fois la migration lancée, les éléments system, vendor et Les partitions product sont incomplètes jusqu'à ce que la copie soit terminée. Si l'appareil est rétablir la configuration d'usine au cours de ce processus, soit par le biais d'une restauration des paramètres de l'appareil, l'appareil serait impossible à démarrer.

Avant d'effacer /data, terminez la fusion lors de la récupération ou du rollback, en fonction l'état de l'appareil:

  • Si la nouvelle compilation a bien démarré auparavant, terminez la migration.
  • Sinon, effectuez un rollback vers l'ancien emplacement: <ph type="x-smartling-placeholder">
      </ph>
    • Pour les partitions dynamiques, revenez à l'état précédent.
    • Pour les partitions statiques, définissez l'emplacement actif sur l'ancien emplacement.

Le bootloader et fastbootd peuvent effacer la partition /data si le l'appareil est déverrouillé. Bien que fastbootd puisse forcer la migration à se terminer, le le bootloader. Le bootloader ne sait pas si une fusion est effectuée ou non la progression, ou quels blocs dans /data constituent les partitions du système d'exploitation. Les appareils doivent empêcher l'utilisateur de rendre l'appareil inutilisable à son insu (maçonnage) en en procédant comme suit:

  1. Implémenter le HAL de contrôle de démarrage pour que le bootloader puisse lire l'ensemble de valeurs par la méthode setSnapshotMergeStatus().
  2. Si l'état de fusion est MERGING ou si l'état de fusion est SNAPSHOTTED et que celui-ci remplace celui que vous venez de mettre à jour, une demande d'effacement userdata, metadata ou la partition stockant l'état de fusion doit être rejetés dans le bootloader.
  3. Implémentez la commande fastboot snapshot-update cancel pour que les utilisateurs puissent au bootloader qu'ils veulent contourner ce mécanisme de protection.
  4. Modification des outils ou des scripts de clignotement personnalisés pour émettre fastboot snapshot-update cancel lors du flashage de l'ensemble de l'appareil. Vous pouvez le faire sans risque, car flasher l'ensemble de l'appareil supprime l'OTA. Les outils peuvent détecter cette commande au moment de l'exécution en implémentant fastboot getvar snapshot-update-status. Ce permet de différencier les conditions d'erreur.

Exemple

struct VirtualAbState {
    uint8_t StructVersion;
    uint8_t MergeStatus;
    uint8_t SourceSlot;
};

bool ShouldPreventUserdataWipe() {
    VirtualAbState state;
    if (!ReadVirtualAbState(&state)) ...
    return state.MergeStatus == MergeStatus::MERGING ||
           (state.MergeStatus == MergeStatus::SNAPSHOTTED &&
            state.SourceSlot != CurrentSlot()));
}

Modifications apportées à l'outil de démarrage rapide

Android 11 apporte les modifications suivantes au fastboot protocole:

  • getvar snapshot-update-status : renvoie la valeur que la commande de contrôle HAL communiqué au bootloader: <ph type="x-smartling-placeholder">
      </ph>
    • Si l'état est MERGING, le bootloader doit renvoyer merging.
    • Si l'état est SNAPSHOTTED, le bootloader doit renvoyer snapshotted.
    • Sinon, le bootloader doit renvoyer none.
  • snapshot-update merge : termine une opération de fusion, en démarrant vers restauration/fastbootd si nécessaire. Cette commande n'est valide que si snapshot-update-status est merging, et n'est compatible qu'avec fastbootd.
  • snapshot-update cancel : définit l'état de fusion du HAL de la commande de démarrage sur CANCELLED Cette commande n'est pas valide lorsque l'appareil est verrouillé.
  • erase ou wipe : erase ou wipe de metadata, userdata, ou une partition contenant l'état de fusion du HAL du contrôle de démarrage doit vérifier l'état de fusion de l'instantané. Si l'état est MERGING ou SNAPSHOTTED, l'appareil doit annuler l'opération.
  • set_active : commande set_active qui modifie l'emplacement actif doit vérifier l'état de la fusion de l'instantané. Si l'état est MERGING, l'appareil doit annuler l'opération. L'emplacement peut être modifié en toute sécurité SNAPSHOTTED.

Ces modifications sont conçues pour éviter de rendre accidentellement un appareil impossible à démarrer, mais ils peuvent perturber les outils automatisés. Lorsque les commandes sont utilisées permettant de flasher toutes les partitions, comme l'exécution de fastboot flashall, il est recommandé d'utiliser le flux suivant:

  1. Requête getvar snapshot-update-status.
  2. Si la valeur est merging ou snapshotted, émettez snapshot-update cancel.
  3. Suivez les étapes de clignotement.

Réduire les besoins de stockage

Appareils qui ne disposent pas d'un espace de stockage A/B complet alloué en mode Super et qui attendent d'utiliser /data si nécessaire, nous vous recommandons vivement d'utiliser le mappage de blocs . L'outil de mappage de blocs assure la cohérence de l'allocation de blocs entre les compilations. ce qui réduit les écritures inutiles sur l'instantané. Reportez-vous à la section Réduire Taille OTA.

Méthodes de compression OTA

Les packages OTA peuvent être ajustés pour différentes métriques de performances. Avantages d'Android plusieurs méthodes de compression compatibles (gz, lz4, zstd et none) qui doivent faire des compromis entre le temps d'installation, l'utilisation de l'espace de stockage COW, le temps de démarrage et l'instantané. lors de la fusion. L'option activée par défaut pour les abdos virtuels avec compression est la gz compression method Remarque: performances relatives entre les méthodes de compression dépend de la vitesse du processeur et du débit de stockage, qui peut varier en fonction sur l'appareil. PostInstall est désactivé dans tous les packages OTA générés ci-dessous. ralentit légèrement le démarrage. La taille totale de la partition dynamique d'un ota full sans compression est de 4,81 Go).

OTA supplémentaire sur le Pixel 6 Pro

Temps d'installation sans phase post-installation Utilisation de l'espace de travail (COW) Après le démarrage OTA Heure de fusion de l'instantané
GZ 24 min 1,18 Go 40,2 s 45,5 s
LZ4 13 min 1,49 Go 37,4 s 37,1 s
none 13 min 2,90 Go 37,6 s 40,7 s

OTA complète sur le Pixel 6 Pro

Temps d'installation sans phase post-installation Utilisation de l'espace de COW Après le démarrage OTA Heure de fusion de l'instantané
GZ 23 min 2,79 Go 24,9 s 41,7 s
LZ4 12 min 3,46 Go 20 s 25,3 s
none 10 min 4,85 Go 20,6 s 29,8 s