Android 10 introduit un 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 OTA Android é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 pour le démarrage anticipé, le rollback n'est pas pris 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 sa modification. La fonctionnalité UDC y parvient grâce aux fonctionnalités de point de contrôle du système de fichiers, à une implémentation alternative lorsque le système de fichiers n'est pas compatible avec les points de contrôle, à l'intégration au mécanisme de démarrage A/B tout en prenant en charge les mises à jour autres que A/B, et à la prise en charge de la liaison de version de clé et de la prévention du rollback de clé.
Impact sur l'utilisateur
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 de la part d'utilisateurs rencontrant des problèmes pendant le processus de mise à jour. Toutefois, en cas d'échec d'une mise à jour OTA, les utilisateurs peuvent remarquer que l'appareil redémarre plusieurs fois.
Fonctionnement
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 sur tous les noyaux courants compatibles avec les appareils équipés d'Android 10.
Pour les autres systèmes de fichiers, l'UDC utilise un appareil virtuel de mappage d'appareils appelé dm_bow
pour la fonctionnalité de point de contrôle. dm_bow
se trouve entre l'appareil et le système de fichiers. Lorsqu'une partition est installée, un ajustement est émis, ce qui amène le système de fichiers à exécuter des commandes de tri sur tous les blocs libres. dm_bow
intercepte ces coupures et les utilise pour configurer une liste de blocage gratuite. Les lectures et les écritures sont ensuite envoyées à l'appareil sans modification, mais avant qu'une écriture ne soit autorisée, les données nécessaires à une restauration sont sauvegardées dans 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 disque pour permettre à l'appareil de restaurer tout point de contrôle actuel. init
appelle ensuite la fonction needsCheckpoint
pour déterminer si l'appareil est à l'état A/B du bootloader ou s'il a défini le nombre de tentatives de mise à jour. Si l'une des deux valeurs est "true", Android appelle createCheckpoint
pour ajouter des options d'installation ou créer un appareil dm_bow
.
Une fois la partition installée, le code de point de contrôle est appelé pour émettre des modifications.
Le processus de démarrage se poursuit alors 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 Keymaster
Les clés Keymaster 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 daemon d'intégrité vérifie qu'il y a suffisamment d'espace disque pour créer un point de contrôle. Le daemon de santé se trouve dans cp_healthDaemon
dans Checkpoint.cpp
.
Le daemon d'état présente les comportements suivants, qui peuvent être configurés :
ro.sys.cp_msleeptime
: contrôle la fréquence à laquelle l'appareil vérifie l'utilisation du disque.ro.sys.cp_min_free_bytes
: contrôle la valeur minimale recherchée par le daemon de vérification de l'état.ro.sys.cp_commit_on_full
: indique si le daemon de santé redémarre l'appareil ou effectue le point de contrôle et continue lorsque le disque est plein.
API de point de contrôle
La fonctionnalité UDC utilise les API de point de contrôle. Pour les autres API utilisées par UDC, consultez IVold.aidl
.
void startCheckpoint(int retry)
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 avec point de contrôle, tels que userdata, ne soient montés en lecture/écriture après le redémarrage. Si le nombre de nouvelles tentatives est positif, l'API gère le suivi des nouvelles tentatives, et le programme de mise à jour appelle needsRollback
pour vérifier si un rollback de la mise à jour est nécessaire. Si le nombre de tentatives est -1
, l'API s'en remet à l'évaluation du bootloader A/B.
Cette méthode n'est pas appelée lors d'une mise à jour A/B normale.
void commitChanges()
Valide les modifications.
Le framework appelle cette méthode après le redémarrage lorsque les modifications sont prêtes à être validées. Cette méthode est appelée avant que les données (telles que les images, les vidéos, les SMS et les accusés de réception du serveur) ne soient écrites dans userdata et avant BootComplete
.
Si aucune mise à jour active avec point de contrôle n'existe, cette méthode n'a aucun effet.
AbandonnerChanges()
Force le redémarrage et revient au point de contrôle. Abandonne toutes les modifications de userdata 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. Les entrées de journal
sont générées.
bool needRollback()
Détermine si un rollback est nécessaire.
Sur les appareils sans point de contrôle, renvoie false
. Sur les appareils avec point de contrôle, renvoie true
lors d'un démarrage sans point de contrôle.
Implémenter l'UDC
Implémentation de référence
Pour voir un exemple d'implémentation de l'UDC, consultez dm-bow.c. Pour en savoir plus sur cette fonctionnalité, consultez dm-bow.txt.
Configuration
Dans on fs
de votre fichier init.hardware.rc
, assurez-vous d'avoir :
mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --early
Dans on late-fs
de 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 associé au tag 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
L'UDC nécessite une partition de métadonnées pour stocker le nombre de tentatives de non-démarrage et les clés. Configurez une partition de métadonnées et installez-la de manière anticipée sur /metadata
.
Dans votre fichier fstab.hardware
, assurez-vous que /metadata
comporte le tag 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 des 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 est compatible avec les points de contrôle. Pour en savoir plus, consultez la section Fonctionnalité de point de contrôle dans différents systèmes de fichiers.
Ajoutez l'indicateur checkpoint=fs
à la section <fs_mgr_flags>
de fstab pour l'appareil installé à /data
.
Systèmes autres que F2FS
Pour les systèmes autres que F2FS, dm-bow
doit être activé dans la configuration du noyau.
Ajoutez l'indicateur checkpoint=block
à la section <fs_mgr_flags>
de fstab pour l'appareil installé à /data
.
Vérifier les journaux
Des entrées de journal sont générées lorsque les API Checkpoint sont appelées.
Validation
Pour tester votre implémentation de l'UDC, exécutez l'ensemble de tests VTS VtsKernelCheckpointTest
.