Racine en lecture seule : préserver configuration, journaux et état des mises à jour
Un système de fichiers racine Linux en lecture seule peut maintenir l’image logicielle stable pendant l’exploitation courante, mais le produit a toujours besoin d’un état modifiable. Les paramètres réseau doivent survivre au redémarrage, les journaux nécessitent une destination limitée et une mise à jour doit préserver assez d’informations pour permettre la restauration. Il faut donc attribuer à chaque catégorie de données une durée de vie, un responsable et une politique en cas de défaillance.
Commencer par inventorier les écritures
Pour chaque service, indiquez ce qu’il écrit, à quel moment, en quelle quantité maximale et ce qui se passe si l’écriture échoue. Incluez les programmes du début d’amorçage, les clients DHCP, l’identité SSH, l’état de l’horloge, les bases de données et les fichiers de vidage après plantage. Même une application qui écrit rarement peut empêcher le démarrage si son chemin par défaut se trouve sur un montage en lecture seule.
| Catégorie de données | Emplacement typique | Comportement requis |
|---|---|---|
| Binaires système et paramètres d’usine | Système racine en lecture seule | Remplacés par une mise à jour logicielle contrôlée |
| Sockets d’exécution, fichiers PID et données temporaires | tmpfs limité sous /run ou /tmp | Recréés à chaque démarrage |
| Configuration client | Répertoire applicatif persistant | Validée, versionnée et conservée pendant les mises à jour prises en charge |
| Identité et identifiants d’accès de l’appareil | Stockage persistant à accès restreint ou protégé matériellement | Provisionnement unique et politique explicite de réinitialisation |
| Diagnostics | Zone de journaux volatile et/ou persistante limitée | Rétention, confidentialité et budgets de stockage appliqués |
| Métadonnées et zone de préparation des mises à jour | Zone persistante réservée ou emplacement inactif | Conservées au cours des transitions de restauration requises |
Ces chemins décrivent des rôles, pas un plan de partitionnement universel. Une carte eMMC, une petite mémoire NOR et une NAND brute demandent des intégrations différentes. Choisissez un système de fichiers et une organisation des mises à jour compatibles avec le BSP, le chargeur et la technologie flash réels.

Choisir la couche immuable et les limites d’écriture
SquashFS est un système de fichiers compressé en lecture seule. Une racine ext4 montée en lecture seule constitue une autre possibilité, avec d’autres contraintes d’image et de restauration. Aucun de ces choix n’authentifie à lui seul le logiciel exécuté. Si cette vérification est nécessaire, concevez une chaîne de confiance : dm-verity vérifie l’intégrité des blocs par rapport à une empreinte racine de confiance et doit s’intégrer à un chemin d’amorçage fiable.
Préférez des chemins modifiables propres à l’application à un /etc entièrement accessible en écriture. Gardez les valeurs par défaut dans l’image et stockez séparément les personnalisations explicites du client. Pour un logiciel ancien qui exige un chemin fixe, un montage bind peut y présenter un répertoire applicatif persistant. Créez les points de montage dans l’image et établissez les droits de propriété avant le lancement du service.
Un OverlayFS couvrant toute la racine peut accueillir des logiciels comportant de nombreuses écritures sur des chemins codés en dur, mais ajoute des comportements à gérer lors des mises à jour. Un ancien fichier de la couche supérieure peut masquer un fichier corrigé de la nouvelle image inférieure. Les marqueurs de suppression peuvent également maintenir une vue obsolète. Définissez si la couche supérieure est jetable, migrée ou liée à une génération d’image précise.
Avec OverlayFS, le système supérieur modifiable doit prendre en charge les attributs étendus et les informations d’entrées de répertoire nécessaires ; le répertoire de travail doit être vide et situé sur le même système de fichiers que le répertoire supérieur. Consultez la documentation OverlayFS du noyau correspondant au noyau déployé. Ne considérez pas des versions quelconques de noyaux fournisseurs comme interchangeables.
Faire de l’ordre de démarrage une condition de bon fonctionnement
Montez le stockage persistant, vérifiez son identité et son organisation attendues, initialisez les répertoires nécessaires, effectuez les migrations approuvées, puis seulement lancez les applications. Ne basculez pas silencieusement sur un répertoire RAM vide si une configuration persistante essentielle manque. Choisissez un mode de restauration identifiable ou un mode dégradé documenté.
Pour une application ancienne, l’exemple suivant illustre la relation entre les chemins après le montage réussi du volume de données. Les deux répertoires doivent déjà exister et leurs permissions doivent correspondre au compte du service. Intégrez ces étapes au système d’initialisation retenu au lieu de les exécuter tard pendant le démarrage.
# /data is the verified, mounted persistent filesystem.
# /etc/myapp is a mount point created in the rootfs image.
mount --bind /data/config/myapp /etc/myapp
# Start myapp only after this mount succeeds.
Les dépendances systemd et les scripts BusyBox/SysV expriment l’ordre différemment. Examinez le squelette Buildroot réel, le système d’initialisation sélectionné et les scripts de service. Consultez /proc/mounts sur la cible pour établir les montages effectifs, notamment pour savoir si un échec a laissé accessible un simple répertoire sous-jacent.
Préserver la configuration malgré une écriture interrompue
Validez toute nouvelle configuration avant son activation. Pour un format constitué d’un fichier, une séquence de validation applicative classique écrit un fichier temporaire dans le même répertoire, le synchronise, le renomme à la place du fichier courant, puis synchronise le répertoire. Vérifiez chaque valeur de retour et gardez une génération connue comme valide si le produit exige une restauration.
validate(candidate)
write(temp_in_same_directory, candidate)
fsync(temp_file)
rename(temp_file, active_file)
fsync(parent_directory)
report_success()
Il s’agit de pseudocode, pas d’un utilitaire directement exécutable. Appliquez les permissions avant de publier le nouveau fichier, gérez les écritures concurrentes et utilisez une base transactionnelle si plusieurs enregistrements doivent changer ensemble. La documentation Linux de fsync explique pourquoi synchroniser seulement le fichier ne rend pas nécessairement son entrée de répertoire persistante. La durabilité dépend encore du système de fichiers, du pilote et du support ; testez les coupures sur le matériel réel.
Attribuer des budgets distincts aux journaux et fichiers temporaires
Un tmpfs utilise la mémoire virtuelle, peut employer le swap s’il est activé et perd son contenu lors du démontage. Limitez octets et inodes, puis intégrez ce budget aux essais de mémoire de pointe. Un gros répertoire de journaux en RAM sans plafond peut épuiser la mémoire d’une application par ailleurs saine.
Pour les images systemd, Storage=volatile garde les données du journal dans /run/log/journal ; le mode persistant utilise /var/log/journal lorsque cet emplacement est disponible. Configurez RuntimeMaxUse ou SystemMaxUse selon le mode, en suivant la documentation journald de la version livrée. BusyBox syslog possède ses propres paramètres de taille, rotation et destination.
Réservez l’espace de configuration et de mise à jour indépendamment des diagnostics volumineux. De simples répertoires sur un même système de fichiers n’isolent pas les capacités ; utilisez des quotas, partitions ou réservations explicites adaptés. Définissez quels événements doivent survivre à une coupure et masquez les identifiants secrets. La journalisation distante n’aide que si les pertes de connexion, la croissance des files et les interruptions de livraison ont un comportement défini.
Concevoir la persistance avec le retour arrière
Des emplacements logiciels A/B ne fournissent pas automatiquement des données applicatives A/B. Une nouvelle application peut migrer une base commune vers un format illisible par l’ancienne. Les possibilités comprennent des schémas rétrocompatibles, des générations de données séparées ou une procédure de restauration explicitement testée. Les recommandations de RAUC sur le stockage présentent les partitions partagées et redondantes et précisent que la migration requiert un traitement propre au produit.
Empêchez les fichiers de préparation de mise à jour de saturer le stockage de configuration. Distinguez paquet téléchargé, paquet vérifié, emplacement d’amorçage sélectionné et démarrage sain confirmé. Ne persistez que l’état nécessaire au système de mise à jour choisi. La réinitialisation d’usine doit faire l’objet d’un contrat écrit indiquant si elle efface paramètres client, journaux conservés, identifiants d’accès et identité de l’appareil ; ces catégories demandent souvent des traitements différents.
Essais de réception et diagnostic
| Défaillance injectée | Résultat attendu à définir | Premiers éléments à examiner |
|---|---|---|
| Coupure pendant la validation d’une configuration | Ancienne ou nouvelle génération valide, jamais de paramètres corrompus acceptés silencieusement | Validation de configuration, marqueurs de génération et erreurs du système de fichiers |
| Volume persistant absent ou corrompu | Comportement de restauration documenté | Journal de montage, identité du support et ordre de lancement |
| Capacité ou inodes des journaux épuisés | Politique de configuration et de mise à jour toujours respectée | Capacité, occupation des inodes et erreurs du journaliseur |
| Mise à jour suivie d’un retour arrière | Ancien logiciel capable d’utiliser les données conservées ou restaurées | Versions des schémas et journal de migration |
| Démarrage à froid après forte utilisation des fichiers temporaires | État d’exécution recréé dans le budget mémoire | Limites tmpfs et relevés des pics mémoire |
| Nouvelle racine avec ancien overlay | Nouveaux paramètres par défaut et binaires visibles comme prévu | Fichiers supérieurs, marqueurs de suppression et politique de migration |
Si les paramètres disparaissent, vérifiez d’abord que le chemin modifiable est persistant et monté avant usage. Si un ancien comportement subsiste après mise à jour, examinez les masquages de l’overlay et la configuration conservée. Si un service signale un « système de fichiers en lecture seule », identifiez l’écriture précise au lieu de remonter toute la racine en écriture. Ces essais exigent une injection contrôlée de défaillances en laboratoire et une procédure de restauration convenue ; aucun résultat de coupure n’est revendiqué ici.
Le service de diagnostic firmware et BSP d’Obeita constitue une entrée pertinente pour examiner stockage et amorçage. Le projet livré d’IHM Linux/Qt apporte un contexte de terminal apparenté. Ce cas ne prouve pas la validation de l’architecture de persistance décrite ici.