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.

Des racines en lecture seule alimentent les applications, avec des zones distinctes pour l’exécution volatile, la configuration durable et les journaux limités avec l’état des mises à jour.
Figure 1. Attribuez à chaque écriture une destination et une durée de vie explicites. Le retour arrière logiciel exige aussi des données compatibles ou restaurables. Le schéma est légendé en anglais.

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.

Publications similaires