Point de contrôle des données utilisateur

Android 10 introduit le point de contrôle des données utilisateur (UDC), qui permet à Android de revenir à son état précédent en cas d'échec d'une mise à jour Android Over-the-Air (OTA). Avec UDC, si une mise à jour Android OTA échoue, l'appareil peut revenir en toute sécurité à son état précédent. Bien que les mises à jour A/B résolvent ce problème en cas de démarrage anticipé, la restauration n'est pas prise en charge lorsque la partition de données utilisateur (montée sur /data ) est modifiée.

UDC permet à l'appareil de rétablir la partition de données utilisateur même après avoir été modifiée. La fonctionnalité UDC y parvient grâce à des capacités de point de contrôle pour le système de fichiers, une implémentation alternative lorsque le système de fichiers ne prend pas en charge les points de contrôle, une intégration avec le mécanisme A/B du chargeur de démarrage tout en prenant également en charge les mises à jour non-A/B et la prise en charge de la liaison de version de clé. et la prévention de la restauration des clés.

Impact sur les utilisateurs

La fonctionnalité UDC améliore l'expérience de mise à jour OTA pour les utilisateurs, car moins d'utilisateurs perdent leurs données en cas d'échec d'une mise à jour OTA. Cela peut réduire le nombre d'appels d'assistance d'utilisateurs rencontrant des problèmes pendant le processus de mise à jour. Cependant, lorsqu'une mise à jour OTA échoue, les utilisateurs peuvent remarquer que l'appareil redémarre plusieurs fois.

Comment ça fonctionne

Fonctionnalité de point de contrôle dans différents systèmes de fichiers

Pour le système de fichiers F2FS, UDC ajoute la fonctionnalité de point de contrôle au noyau Linux 4.20 en amont et la rétroporte vers tous les noyaux courants pris en charge par les appareils exécutant Android 10.

Pour les autres systèmes de fichiers, UDC utilise un périphérique virtuel de mappage de périphérique appelé dm_bow pour la fonctionnalité de point de contrôle. dm_bow se situe entre le périphérique et le système de fichiers. Lorsqu'une partition est montée, un trim est émis, ce qui oblige le système de fichiers à émettre des commandes trim sur tous les blocs libres. dm_bow intercepte ces coupes et les utilise pour établir une liste de blocage gratuite. Les lectures et les écritures sont ensuite envoyées au périphérique sans modification, mais avant qu'une écriture ne soit autorisée, les données nécessaires à une restauration sont sauvegardées sur un bloc libre.

Processus de point de contrôle

Lorsqu'une partition avec l'indicateur checkpoint=fs/block est montée, Android appelle restoreCheckpoint sur le lecteur pour permettre à l'appareil de restaurer n'importe quel point de contrôle actuel. init appelle ensuite la fonction needsCheckpoint pour déterminer si le périphérique est dans un état A/B du chargeur de démarrage ou a défini le nombre de tentatives de mise à jour. Si l’un ou l’autre est vrai, Android appelle createCheckpoint pour ajouter des indicateurs de montage ou créer un périphérique dm_bow .

Une fois la partition montée, le code du point de contrôle est appelé pour émettre des trims. Le processus de démarrage se poursuit ensuite normalement. À LOCKED_BOOT_COMPLETE , Android appelle commitCheckpoint pour valider le point de contrôle actuel et la mise à jour se poursuit normalement.

Gérer les clés principales

Les clés principales sont utilisées pour le chiffrement de l'appareil ou à d'autres fins. Pour gérer ces clés, Android retarde les appels de suppression de clé jusqu'à ce que le point de contrôle soit validé.

Surveiller la santé

Un démon d'intégrité vérifie qu'il y a suffisamment d'espace disque pour créer un point de contrôle. Le démon de santé se trouve dans cp_healthDaemon dans Checkpoint.cpp .

Le démon d'intégrité a les comportements suivants qui peuvent être configurés :

  • ro.sys.cp_msleeptime : contrôle la fréquence à laquelle le périphérique vérifie l'utilisation du disque.
  • ro.sys.cp_min_free_bytes : contrôle la valeur minimale recherchée par le démon d'intégrité.
  • ro.sys.cp_commit_on_full : contrôle si le démon d'intégrité redémarre le périphérique ou valide le point de contrôle et continue lorsque le disque est plein.

API de point de contrôle

Les API Checkpoint sont utilisées par la fonctionnalité UDC. Pour les autres API utilisées par UDC, voir IVold.aidl .

void startCheckpoint (int nouvelle tentative)

Crée un point de contrôle.

Le framework appelle cette méthode lorsqu'il est prêt à démarrer une mise à jour. Le point de contrôle est créé avant que les systèmes de fichiers soumis à un point de contrôle tels que les données utilisateur ne soient montés R/W après le redémarrage. Si le nombre de tentatives est positif, l'API gère les tentatives de suivi et le programme de mise à jour appelle needsRollback pour vérifier si une restauration de la mise à jour est requise. Si le nombre de tentatives est -1 , l'API s'en remet au jugement du chargeur de démarrage A/B.

Cette méthode n’est pas appelée lors d’une mise à jour A/B normale.

annuler commitChanges()

Valide les modifications.

Le framework appelle cette méthode après le redémarrage lorsque les modifications sont prêtes à être validées. Ceci est appelé avant que les données (telles que les images, les vidéos, les SMS, la réception du serveur) ne soient écrites dans les données utilisateur et avant BootComplete .

S’il n’existe aucune mise à jour active par point de contrôle, cette méthode n’a aucun effet.

abandonnerChanges()

Force le redémarrage et revient au point de contrôle. Abandonne toutes les modifications des données utilisateur depuis le premier redémarrage.

Le framework appelle cette méthode après le redémarrage mais avant commitChanges . retry_counter est diminué lorsque cette méthode est appelée. Des entrées de journal sont générées.

bool a besoin de Rollback()

Détermine si une restauration est requise.

Sur les appareils sans point de contrôle, renvoie false . Sur les appareils à point de contrôle, renvoie true lors d'un démarrage sans point de contrôle.

Implémenter la CDU

Implémentation de référence

Pour un exemple de la façon dont UDC peut être implémenté, voir dm-bow.c . Pour une documentation supplémentaire sur la fonctionnalité, consultez dm-bow.txt .

Installation

Dans on fs dans votre fichier init.hardware.rc , assurez-vous d'avoir :

mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --early

Dans on late-fs dans votre fichier init.hardware.rc , assurez-vous d'avoir :

mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --late

Dans votre fichier fstab.hardware , assurez-vous que /data est étiqueté comme latemount .

/dev/block/bootdevice/by-name/userdata              /data              f2fs
noatime,nosuid,nodev,discard,reserve_root=32768,resgid=1065,fsync_mode=nobarrier
latemount,wait,check,fileencryption=ice,keydirectory=/metadata/vold/metadata_encryption,quota,formattable,sysfs_path=/sys/devices/platform/soc/1d84000.ufshc,reservedsize=128M,checkpoint=fs

Ajouter une partition de métadonnées

UDC nécessite une partition de métadonnées pour stocker le nombre de tentatives et les clés du non-chargeur de démarrage. Configurez une partition de métadonnées et montez-la tôt sur /metadata .

Dans votre fichier fstab.hardware , assurez-vous que /metadata est étiqueté comme earlymount ou first_stage_mount .

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

Initialisez la partition avec tous les zéros.

Ajoutez les lignes suivantes à BoardConfig.mk :

BOARD_USES_METADATA_PARTITION := true
BOARD_ROOT_EXTRA_FOLDERS := existing_folders metadata

Mettre à jour les systèmes

Systèmes F2FS

Pour les systèmes qui utilisent F2FS pour formater les données, assurez-vous que votre version de F2FS prend en charge les points de contrôle. Pour plus d'informations, consultez Fonctionnalité Checkpoint dans différents systèmes de fichiers .

Ajoutez l'indicateur checkpoint=fs à la section <fs_mgr_flags> de fstab pour le périphérique monté sur /data .

Systèmes non F2FS

Pour les systèmes non F2FS, dm-bow doit être activé dans la configuration du noyau.

Ajoutez l'indicateur checkpoint=block à la section <fs_mgr_flags> de fstab pour le périphérique monté sur /data .

Vérifier les journaux

Les entrées de journal sont générées lorsque les API Checkpoint sont appelées.

Validation

Pour tester votre implémentation UDC, exécutez l'ensemble de tests VTS VtsKernelCheckpointTest .