Dans les systèmes embarqués il y a toujours un risque de coupure d'alimentation en plein fonctionnement et donc de perdre des données.
Perdre des données est un problème, mais souvent le plus critique est de ne pas corrompre les données existantes ou même le système.
Nous allons nous intéresser à quelques techniques pour prévenir ce risque dans le cas d'utilisation d'une mémoire flash.
Un système de fichier adapté
Les mémoires flash sont des technologies particulières, il faut donc utiliser des systèmes de fichiers adaptés à ces dernières, ce qui n'est pas le cas des systèmes de fichiers génériques.
On peut citer JFFS2 pour les anciens kernels et UBIFS pour les plus récents.
Ces systèmes de fichiers ont été conçus pour les mémoires flash et prennent des dispositions particulières pour éviter d'être corrompus en cas de perte brutale d'alimentation.
Remplacement atomique
Si l'application embarquée doit mettre à jour un fichier, par exemple un fichier de configuration, plutôt que de le modifier sur place, il faut préférer un remplacement atomique. Ainsi en cas de redémarrage pendant l'opération, soit l'ancien fichier sera préservé, soit le nouveau mais en aucun cas un fichier incomplet.
Techniquement, un remplacement atomique est réalisé en trois étapes:
- L'écriture du contenu dans un fichier temporaire ;
- La synchronisation sur le support (à l'aide de
fsync(fd)
) de ce fichier ; - Le remplacement atomique du fichier destination (à l'aide de
rename()
).
Note: L'utilisation de fsync
est souvent oubliée ou même délibérément omise pour des raisons de performance (surtout avec ext3 et ext4). Vous pourriez avoir à auditer votre système pour corriger ce type de problème.
Base de données transactionnelle
Pour un stockage de données plus complexes qu'un simple fichier de configuration, l'utilisation d'une base de donnée transactionnelle adaptée est à privilégier. En effet les bases de données gèrent déjà cette problématique, il suffit de vérifier qu'elle remplit les propriétés ACID (Le moteur historique de MySQL, MyISAM, ne les remplit pas).
Pour prendre un exemple dans l'embarqué grand public (exemple sous Android), les données des applications sont stockées dans des bases SQLite. Ce choix répond à cette problématique. En effet cette base de donnée - développée pour l'aéronautique - a été conçue pour résister au plantage du programme, de l'OS et aux pertes d'alimentation ; comme indiqué sur la page du projet (voir bibliographie).
Conclusion
Au delà de ces quelques bonnes pratiques, il reste important de bien connaître les limitations de toute la chaîne, du logiciel au matériel car la robustesse à la perte d'alimentation concernent tous les niveaux du système. Quand le courant disparaît il ne fait pas de discrimination, tout s'arrête !
Bibliographie
- JFFS2 PDF
- UBI Un LVM pour flash
- UBIFS
- Page Wikipedia ACID
- SQLite is Transactional
[...] m’a fait penser au mécanisme de remplacement atomique que je vous présentais dans un précédent article. Il est effectivement possible d’utiliser O_TMPFILE dans ce scénario, mais comme rename [...]