Implémenter Virtual A/B - correctifs

Sélectionnez les correctifs suivants pour résoudre les problèmes connus suivants.

Vérifiez correctement l’espace allouable lors du chargement latéral

Le chargement latéral d'un package OTA complet sur un périphérique virtuel A/B doté d'une super partition d'une taille inférieure à *2 * somme (taille des groupes de mise à jour)* peut échouer avec ce qui suit dans le journal de récupération /tmp/recovery.log :

The maximum size of all groups with suffix _b (...) has exceeded half of allocatable space for dynamic partitions ...

Voici un exemple de journal :

[INFO:dynamic_partition_control_android.cc(1020)] Will overwrite existing partitions. Slot A may be unbootable until update finishes!
[...]
[ERROR:dynamic_partition_control_android.cc(803)] The maximum size of all groups with suffix _b (2147483648) has exceeded half of allocatable space for dynamic partitions 1073741824.

Si vous rencontrez ce problème, sélectionnez CL 1399393 , reconstruisez et flashez la partition de démarrage ou la partition de récupération si le périphérique n'utilise pas la récupération comme démarrage.

Correction d'un défaut de segmentation lors de la fusion

Après avoir appliqué une mise à jour OTA, pendant le processus de fusion VAB, un appel à update_engine_client --cancel provoque le blocage de CleanupPreviousUpdateAction . Une erreur potentielle de pointeur sauvage existe également lorsque markSlotSuccessful arrive en retard.

Ce problème a été résolu en ajoutant la fonction StopActionInternal . CleanupPreviousUpdateAction annule les tâches en attente lors de la destruction. Il conserve une variable qui suit l'ID de tâche de la tâche en attente dans la boucle de messages. Lors de la destruction, la tâche en attente est annulée pour éviter une erreur de segmentation.

Assurez-vous que les modifications suivantes figurent dans votre arborescence source Android 11 pour corriger les plantages SIGSEGV dans update_engine lors de la fusion :

  • CL 1439792 (un prérequis au CL 1439372)
  • CL 1439372 ( CleanupPreviousUpdateAction : annuler les tâches en attente lors de la destruction)
  • CL 1663460 (corrige l'erreur potentielle du pointeur sauvage lorsque markSlotSuccessful arrive en retard)

Correction d'un changement d'emplacement incorrect VAB, après la mise à jour OTA

Sous Android 11 et versions ultérieures, l'échec de la synchronisation d'un commutateur d'emplacement dans un appareil après une mise à jour OTA peut mettre un appareil dans un état inutilisable. Si l'implémentation de commutation d'emplacement de votre IBootControl HAL effectue des écritures, vous devez vider ces écritures immédiatement. Si les écritures ne sont pas vidées et que le périphérique redémarre après le démarrage de la fusion, mais avant que le matériel puisse vider l'écriture du commutateur d'emplacement, le périphérique peut revenir à l'emplacement précédent et ne pas démarrer.

Pour un exemple de solution de code, consultez ce CL : CL 1535570 .

Empêcher la fusion prématurée de update_engine

Lorsqu'un appareil démarre (Android 11 et supérieur) et que le démarrage est terminé, update_engine appelle ScheduleWaitMarkBootSuccessful() et WaitForMergeOrSchedule() . Cela démarre le processus de fusion. Cependant, l'appareil redémarre sur l'ancien emplacement. La fusion ayant déjà commencé, le périphérique ne parvient pas à démarrer et devient inutilisable.

Ajoutez les modifications suivantes à votre arborescence source. Notez que CL 1664859 est facultatif.

  • CL 1439792 (un prérequis au CL 1439372)
  • CL 1439372 ( CleanupPreviousUpdateAction : annuler les tâches en attente lors de la destruction)
  • CL 1663460 (corrige l'erreur potentielle du pointeur sauvage lorsque markSlotSuccessful arrive en retard)
  • CL 1664859 (facultatif - ajouter unittest pour CleanupPreviousUpdateAction )

Empêcher la perte ou la corruption de données en raison de métadonnées ignorées

Sous Android 11 et versions ultérieures, si un périphérique de stockage dispose d'un cache de réécriture volatile, dans certaines conditions, les métadonnées d'une fusion terminée sont ignorées, ce qui entraîne une perte ou une corruption de données.

Conditions:

  1. Après avoir terminé une opération de fusion d'un ensemble d'exceptions, merge_callback() a été invoquée.
  2. Les métadonnées ont été mises à jour dans le périphérique COW qui suit l'achèvement de la fusion. (Cette mise à jour du périphérique COW est purgée proprement.)

Résultat : le système est tombé en panne car le cache du périphérique de stockage de la fusion récente n'a pas été vidé.

Consultez ce qui suit pour mettre en œuvre une résolution :

Assurez-vous de la configuration correcte de DM-Verity

Sous Android 11 et versions ultérieures, les appareils peuvent être configurés par inadvertance avec les options dm-verity suivantes :

  • CONFIG_DM_VERITY_AVB=y dans le noyau
  • Le chargeur de démarrage configuré pour utiliser n'importe quel mode Verity (tel que AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE ), sans AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO .

Avec cette configuration de périphérique, toute erreur de vérité entraîne la corruption de la partition vbmeta et rend les périphériques non-A/B inutilisables. De même, si une fusion a commencé, les appareils A/B peuvent également devenir inutilisables. Utilisez uniquement le mode de vérité AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO .

  1. Définissez CONFIG_DM_VERITY_AVB=n dans le noyau
  2. Configurez les appareils pour qu'ils utilisent plutôt le mode AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO .

Pour plus d'informations et à titre pratique, consultez la documentation de Verity : Gestion des erreurs dm-verity .

Ignorer le travail de vérification en réponse à une erreur d'E/S lors d'un arrêt d'urgence du système

Sous Android 11 et versions ultérieures, si un arrêt d'urgence du système est appelé (comme dans le cas d'un arrêt thermique), un périphérique dm peut être actif tandis que le périphérique bloc ne peut plus traiter les demandes d'E/S. Dans cet état, les erreurs d'E/S gérées par les nouvelles requêtes d'E/S dm, ou par celles déjà en cours, peuvent conduire à un état de corruption de la vérité, ce qui constitue une erreur d'appréciation.

Pour ignorer le travail de vérification en réponse à une erreur d'E/S lors de l'arrêt du système, utilisez ce qui suit :

CL 1847875 (ignore le travail de vérification en réponse à une erreur d'E/S lors de l'arrêt)

Assurez-vous que DM_ANDROID_VERITY_AT_MOST_ONCE_DEFAULT_ENABLED est désactivé

Les appareils Android Go exécutant le noyau 4.19 ou une version antérieure peuvent avoir DM_ANDROID_VERITY_AT_MOST_ONCE_DEFAULT_ENABLED=y dans la configuration de leur noyau. Ce paramètre n'est pas compatible avec Virtual A/B et est connu pour provoquer de rares problèmes de corruption de page lorsque les deux sont activés ensemble.

Pour les noyaux 4.19 et versions antérieures, désactivez-le en définissant CONFIG_DM_ANDROID_VERITY_AT_MOST_ONCE_DEFAULT_ENABLED=n dans la configuration du noyau.

Pour les noyaux 5.4 et versions ultérieures, le code a été supprimé et l'option de configuration n'est pas disponible.

Confirmez que le fichier fusionné est correctement configuré

Si vous créez des images système et des images de fournisseur séparément, puis que vous utilisez merge_target_files pour les fusionner, les configurations Virtual A/B peuvent être supprimées de manière incorrecte pendant le processus de fusion. Pour vérifier que les configurations Virtual A/B sont correctes dans le fichier cible fusionné, appliquez les correctifs suivants : CL 2084183 (fusionner les paires clé/val identiques dans les informations de partition dynamique)

Mettre à jour les composants nécessaires

Depuis Android 13, snapuserd a été déplacé du disque virtuel du fournisseur vers le disque virtuel générique. Si votre appareil effectue une mise à niveau vers Android 13, il est possible que le disque virtuel du fournisseur et le disque virtuel générique contiennent une copie de snapuserd . Dans cette situation, Virtual A/B nécessite la copie système de snapuserd . Pour vous assurer que la copie correcte de snapuserd est en place, appliquez CL 2031243 (copiez snapuserd sur first_stage_ramdisk).