Schreibgeschütztes Rootfs: Konfiguration, Protokolle und Update-Zustand sicher erhalten

Ein schreibgeschütztes Linux-Root-Dateisystem kann das Software-Image im laufenden Betrieb unverändert halten, doch das Produkt benötigt weiterhin beschreibbare Zustandsdaten. Netzwerkeinstellungen müssen Neustarts überstehen, Protokolle brauchen ein begrenztes Speicherziel, und Updates müssen genügend Informationen für eine Wiederherstellung erhalten. Die Aufgabe besteht darin, für jede Datenart Lebensdauer, Verantwortlichkeit und Fehlerverhalten ausdrücklich festzulegen.

Mit einer Bestandsaufnahme aller Schreibzugriffe beginnen

Listen Sie für jeden Dienst auf, was er wann schreibt, wie viel er schreiben darf und was bei einem Schreibfehler geschieht. Berücksichtigen Sie frühe Boot-Programme, DHCP-Clients, SSH-Identität, Uhrzustand, Datenbanken und Absturzabbilder. Auch eine Anwendung, die nur selten schreibt, kann den Start verhindern, wenn ihr Standardpfad auf einem schreibgeschützten Dateisystem liegt.

Datenklasse Typischer Speicherort Erforderliches Verhalten
Systemprogramme und Werkseinstellungen Schreibgeschütztes Rootfs Durch kontrolliertes Software-Update ersetzt
Laufzeit-Sockets, PID-Dateien und temporäre Daten Begrenztes tmpfs unter /run oder /tmp Nach jedem Start neu angelegt
Kundenkonfiguration Persistentes Anwendungsverzeichnis Geprüft, versioniert und über unterstützte Updates erhalten
Geräteidentität und Zugangsdaten Zugriffsbeschränkter persistenter oder hardwaregestützter Speicher Eindeutige Provisionierung und ausdrückliche Rücksetzregel
Diagnosedaten Begrenzter flüchtiger und/oder persistenter Protokollbereich Aufbewahrung, Datenschutz und Speicherbudget durchgesetzt
Update-Metadaten und Zwischenspeicherung Reservierter persistenter Bereich oder inaktiver Slot Über erforderliche Wiederherstellungsübergänge erhalten

Die Pfade in dieser Tabelle beschreiben Rollen, keine allgemeingültige Partitionierung. Eine Platine mit eMMC, ein kleines NOR-Gerät und rohes NAND benötigen unterschiedliche Speicherintegration. Wählen Sie Dateisystem und Update-Aufbau passend zum tatsächlichen BSP, Bootloader und Flash-Typ.

Schreibgeschützte Rootfs-Slots versorgen Anwendungen; getrennte Bereiche nehmen flüchtige Laufzeitdaten, dauerhafte Konfiguration sowie begrenzte Protokolle und Update-Zustand auf.
Abbildung 1. Jeder Schreibzugriff erhält ein festgelegtes Ziel und eine Lebensdauer. Software-Rollback verlangt außerdem kompatible oder wiederherstellbare Anwendungsdaten. Die Grafik ist englisch beschriftet.

Unveränderliche Schicht und Schreibgrenzen wählen

SquashFS ist ein komprimiertes, schreibgeschütztes Dateisystem. Eine schreibgeschützt eingebundene ext4-Wurzel ist eine weitere Möglichkeit mit anderen Anforderungen an Image und Wiederherstellung. Keine der beiden Entscheidungen authentifiziert allein die laufende Software. Wenn geprüfte Software erforderlich ist, entwerfen Sie eine Vertrauenskette: dm-verity kontrolliert die Blockintegrität anhand eines vertrauenswürdigen Root-Hashes und muss in einen vertrauenswürdigen Boot-Pfad eingebunden werden.

Bevorzugen Sie anwendungsspezifische Schreibpfade gegenüber einem vollständig beschreibbaren /etc. Belassen Sie die Standardkonfiguration im Image und speichern Sie ausdrückliche Kundenanpassungen getrennt. Für ältere Software mit festem Pfad kann ein Bind-Mount dort ein persistentes Anwendungsverzeichnis bereitstellen. Legen Sie Mount-Punkte im Image an und setzen Sie Eigentümerrechte vor dem Dienststart.

Ein OverlayFS über der gesamten Wurzel kann Software mit vielen fest codierten Schreibpfaden unterstützen, führt aber zusätzliches Update-Verhalten ein. Eine alte Datei in der oberen Schicht kann eine korrigierte Datei im neuen unteren Image verdecken. Löschmarkierungen können ebenfalls eine überholte Sicht erhalten. Definieren Sie, ob die obere Schicht verworfen, migriert oder an eine bestimmte Image-Generation gebunden wird.

Bei OverlayFS muss das beschreibbare obere Dateisystem die erforderlichen erweiterten Attribute und Verzeichniseintragsinformationen unterstützen. Das Arbeitsverzeichnis muss leer sein und auf demselben Dateisystem wie das obere Verzeichnis liegen. Prüfen Sie die Kernel-Dokumentation zu OverlayFS für den eingesetzten Kernel. Behandeln Sie beliebige Hersteller-Kernel nicht als austauschbar.

Die Boot-Reihenfolge als Korrektheitsbedingung behandeln

Binden Sie den persistenten Speicher ein, prüfen Sie seine erwartete Identität und Struktur, initialisieren Sie benötigte Verzeichnisse, führen Sie freigegebene Migrationen aus und starten Sie erst danach die Anwendungen. Fallen Sie bei fehlender wesentlicher Konfiguration nicht unbemerkt auf ein leeres RAM-Verzeichnis zurück. Wählen Sie einen erkennbaren Wiederherstellungsmodus oder einen dokumentierten Modus mit eingeschränkten Funktionen.

Für eine ältere Anwendung zeigt das folgende Beispiel die Pfadbeziehung nach erfolgreichem Einbinden des Datenvolumens. Beide Verzeichnisse müssen bereits existieren und zum Dienstkonto passende Rechte besitzen. Integrieren Sie diese Schritte in das gewählte Init-System, statt sie spät im Boot-Vorgang auszuführen.

# /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.

Systemd-Abhängigkeiten und BusyBox-/SysV-Skripte bilden Reihenfolgen unterschiedlich ab. Prüfen Sie das tatsächliche Buildroot-Grundgerüst, das ausgewählte Init-System und die Dienstskripte. Kontrollieren Sie auf dem Zielgerät /proc/mounts, um die realen Mounts festzustellen, einschließlich eines gewöhnlichen Verzeichnisses, das nach einem fehlgeschlagenen Mount darunter sichtbar geblieben ist.

Konfiguration bei unterbrochenen Schreibvorgängen erhalten

Prüfen Sie eine neue Konfiguration vor ihrer Aktivierung. Für ein Format aus einer einzelnen Datei schreibt eine typische anwendungsseitige Commit-Sequenz eine temporäre Datei im selben Verzeichnis, synchronisiert sie, benennt sie über die aktuelle Datei um und synchronisiert anschließend das Verzeichnis. Prüfen Sie jeden Rückgabewert und erhalten Sie eine bekanntermaßen gültige Generation, wenn das Produkt Wiederherstellung verlangt.

validate(candidate)
write(temp_in_same_directory, candidate)
fsync(temp_file)
rename(temp_file, active_file)
fsync(parent_directory)
report_success()

Dies ist Pseudocode, kein direkt ausführbares Werkzeug. Setzen Sie Dateirechte vor der Veröffentlichung, behandeln Sie gleichzeitige Schreiber und verwenden Sie eine transaktionale Datenbank, wenn mehrere Datensätze gemeinsam geändert werden müssen. Die Linux-Dokumentation zu fsync erklärt, warum das Synchronisieren einer Datei allein deren Verzeichniseintrag nicht unbedingt dauerhaft speichert. Die Dauerhaftigkeit hängt weiterhin von Dateisystem, Treiber und Speichergerät ab; testen Sie Stromausfälle an der tatsächlichen Hardware.

Getrennte Budgets für Protokolle und temporäre Dateien

Ein tmpfs nutzt virtuellen Speicher, kann bei aktivierter Auslagerung Swap verwenden und verliert seinen Inhalt beim Aushängen. Begrenzen Sie Bytes und Inodes und berücksichtigen Sie das Budget bei Tests des maximalen Speicherverbrauchs. Ein großes unbegrenztes RAM-Protokollverzeichnis kann einer ansonsten fehlerfrei arbeitenden Anwendung den Speicher nehmen.

Bei systemd-Images hält Storage=volatile Journal-Daten unter /run/log/journal; persistente Speicherung nutzt, wenn verfügbar, /var/log/journal. Konfigurieren Sie je nach Modus RuntimeMaxUse oder SystemMaxUse anhand der journald-Dokumentation für die ausgelieferte Version. BusyBox syslog benötigt eigene Einstellungen für Größe, Rotation und Ziel.

Reservieren Sie Platz für Konfiguration und Updates unabhängig von umfangreicher Diagnoseausgabe. Verzeichnisse auf einem gemeinsamen Dateisystem bieten allein keine Kapazitätsisolation; nutzen Sie geeignete Quoten, Partitionen oder ausdrückliche Reservierungen. Definieren Sie, welche Ereignisse einen Stromausfall überstehen müssen, und entfernen Sie Zugangsdaten aus Protokollen. Remote-Logging hilft nur, wenn Verbindungsverlust, Warteschlangenwachstum und Übertragungslücken klar geregelt sind.

Persistenz gemeinsam mit Rollback entwerfen

A/B-Software-Slots stellen nicht automatisch A/B-Anwendungsdaten bereit. Eine neue Anwendung kann eine gemeinsame Datenbank in ein Format migrieren, das die alte Anwendung nicht lesen kann. Möglich sind rückwärtskompatible Schemata, getrennte Datengenerationen oder ein ausdrücklich getesteter Wiederherstellungsweg. RAUCs Hinweise zur Datenspeicherung erläutern gemeinsame und redundante Datenpartitionen und stellen klar, dass Migration produktspezifische Umsetzung erfordert.

Verhindern Sie, dass zwischengespeicherte Updates den Konfigurationsspeicher füllen. Unterscheiden Sie ein heruntergeladenes Paket, ein geprüftes Paket, einen ausgewählten Boot-Slot und einen bestätigten erfolgreichen Start. Speichern Sie nur den vom gewählten Update-Framework benötigten Zustand dauerhaft. Für das Zurücksetzen auf Werkseinstellungen muss schriftlich festgelegt sein, ob Kundeneinstellungen, aufbewahrte Protokolle, Zugangsdaten und Geräteidentität gelöscht werden; diese Kategorien brauchen häufig unterschiedliche Behandlung.

Abnahmetests und Fehlersuche

Eingespritzter Fehler Zu definierendes Soll-Ergebnis Zuerst zu prüfende Nachweise
Stromausfall während des Konfigurations-Commits Gültige alte oder neue Generation, keine unbemerkt beschädigten Einstellungen Konfigurationsprüfung, Generationskennzeichen und Dateisystemfehler
Persistentes Volume fehlt oder ist beschädigt Dokumentiertes Wiederherstellungsverhalten Mount-Protokoll, Geräteidentität und Reihenfolge des Anwendungsstarts
Protokollkapazität oder Inodes erschöpft Konfigurations- und Update-Regeln bleiben eingehalten Dateisystemkapazität, Inode-Nutzung und Logger-Fehler
Update mit anschließendem Rollback Alte Software kann erhaltene oder wiederhergestellte Daten verwenden Schema-Versionen und Migrationsprotokoll
Kaltstart nach intensiver Nutzung temporärer Dateien Laufzeitzustand wird innerhalb des Speicherbudgets neu aufgebaut tmpfs-Grenzen und Aufzeichnungen der Speicherspitzen
Neues Rootfs mit bestehendem Overlay Aktualisierte Standardwerte und Programme sind wie vorgesehen sichtbar Dateien der oberen Schicht, Löschmarkierungen und Migrationsregeln

Verschwinden Einstellungen, prüfen Sie zuerst, ob der Schreibpfad persistent und vor seiner Verwendung eingebunden ist. Bleibt nach einem Update altes Verhalten bestehen, untersuchen Sie Overlay-Verdeckung und erhaltene Konfiguration. Meldet ein Dienst „schreibgeschütztes Dateisystem“, ermitteln Sie den konkreten Schreibversuch, statt die gesamte Wurzel pauschal beschreibbar einzubinden. Diese Prüfungen erfordern kontrollierte Fehlerinjektion im Labor und ein vereinbartes Wiederherstellungsverfahren; hier werden keine Stromausfall-Messergebnisse behauptet.

Obeitas Service für Firmware- und BSP-Diagnose ist ein passender Ausgangspunkt für eine Speicher- und Boot-Prüfung. Das gelieferte Linux-/Qt-HMI-Projekt bietet verwandten Terminalkontext. Dieser Fall belegt keine Validierung der hier beschriebenen Persistenzarchitektur.

Ähnliche Beiträge