読み取り専用 rootfs:設定・ログ・更新状態を安全に保持する
読み取り専用の Linux ルートファイルシステムは、通常運転中のソフトウェアイメージを一定に保てますが、製品には書き込み可能な状態データも必要です。ネットワーク設定は再起動後も残り、ログには容量制限のある保存先があり、更新時には復旧に十分な情報を保持しなければなりません。設計の課題は、データの種類ごとに寿命、管理主体、障害時の方針を明確にすることです。
書き込みの一覧から始める
各サービスについて、何を、いつ、最大でどれだけ書き込み、失敗時にどう動くかを列挙します。起動初期のプログラム、DHCP クライアント、SSH 識別情報、時計の状態、データベース、クラッシュダンプも含めます。書き込み頻度が低いアプリケーションでも、既定パスが読み取り専用マウント上にあれば起動を妨げることがあります。
| データ区分 | 代表的な保存先 | 必要な動作 |
|---|---|---|
| システムバイナリーと工場出荷時の既定値 | 読み取り専用 rootfs | 管理されたソフトウェア更新で置き換える |
| 実行時ソケット、PID ファイル、一時データ | /run または /tmp の容量制限付き tmpfs | 起動のたびに再作成する |
| 顧客設定 | 永続的なアプリケーション用ディレクトリ | 検証・バージョン管理し、対応する更新で保持する |
| 機器識別情報と認証情報 | アクセス制限付き永続ストレージまたはハードウェア保護領域 | 一意に設定し、初期化方針を明示する |
| 診断情報 | 容量制限付きの揮発性/永続ログ領域 | 保存期間、プライバシー、容量予算を守る |
| 更新メタデータとステージング | 予約済み永続領域または非アクティブスロット | 必要な復旧遷移を通じて保持する |
この表のパスは役割を示しており、汎用的なパーティション構成ではありません。eMMC 搭載基板、小容量 NOR、raw NAND では、必要なストレージ統合が異なります。実際の BSP、ブートローダー、フラッシュ技術が対応するファイルシステムと更新方式を選びます。

不変層と書き込み境界を選ぶ
SquashFS は圧縮された読み取り専用ファイルシステムです。ext4 のルートを読み取り専用でマウントする設計も可能ですが、イメージと復旧で考慮すべき点は異なります。いずれも、それだけで実行中ソフトウェアの真正性を保証しません。ソフトウェア検証が必要なら信頼の連鎖を設計します。dm-verity は信頼できるルートハッシュに対してブロックの完全性を確認するため、信頼された起動経路との統合が必要です。
/etc 全体を書き込み可能にするより、アプリケーション専用の書き込み先を優先します。既定設定はイメージに残し、顧客が明示的に変更した設定は別に保存します。固定パスを要求する旧ソフトウェアには、bind mount で永続的なアプリケーションディレクトリをその位置に公開できます。マウントポイントはイメージに組み込み、サービス起動前に所有権を設定します。
ルート全体の OverlayFS は、書き込み先を多数ハードコードしたソフトウェアに対応できますが、更新時の動作が増えます。古い上層ファイルが新しい下層イメージの修正済みファイルを隠す場合があります。削除マーカーも古い見え方を維持し得ます。上層を破棄可能とするか、移行するか、特定イメージ世代に結び付けるかを定義します。
OverlayFS の書き込み可能な上層ファイルシステムには、必要な拡張属性とディレクトリエントリー情報への対応が必要です。作業ディレクトリは空であり、上層ディレクトリと同じファイルシステム上になければなりません。配備するカーネルに合わせてカーネルの OverlayFS 文書を確認します。任意のベンダーカーネル版を相互交換可能と考えないでください。
起動順序を正しさの条件にする
永続ストレージをマウントし、想定した識別情報と構成を確認し、必要なディレクトリを初期化し、承認済みの移行を実施してから、アプリケーションを開始します。必須の永続設定が見つからないときに、空の RAM ディレクトリへ無言で切り替えてはいけません。明確な復旧モード、または文書化した機能制限モードを選びます。
次の例は、データボリュームのマウント成功後に、旧アプリケーション向けのパスを対応付けるものです。両ディレクトリは事前に存在し、権限がサービスアカウントと一致していなければなりません。起動の後半で実行するのではなく、選んだ init システムに手順を組み込みます。
# /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 の依存関係と BusyBox/SysV のスクリプトでは、順序の表し方が異なります。実際の Buildroot スケルトン、init の選択、サービススクリプトを調べます。対象機器の /proc/mounts で実際にマウントされた内容を確認し、マウント失敗によって下にある通常ディレクトリが見えているだけではないかも確認します。
書き込み中断から設定を守る
新しい設定は有効化前に検証します。単一ファイル形式では、同じディレクトリに一時ファイルを書き込み、それを同期し、現行ファイルへ rename で置き換え、最後にディレクトリを同期するのが典型的なアプリケーション側の確定手順です。すべての戻り値を確認し、復旧が必要な製品では既知の正常な世代を保持します。
validate(candidate)
write(temp_in_same_directory, candidate)
fsync(temp_file)
rename(temp_file, active_file)
fsync(parent_directory)
report_success()
これは擬似コードであり、そのまま実行できるユーティリティーではありません。新ファイルを公開する前に権限を設定し、同時書き込みを処理し、複数レコードを同時に変更する必要があればトランザクション対応データベースを使用します。Linux の fsync 文書は、ファイルの同期だけではディレクトリエントリーの永続化を必ずしも保証できない理由を説明しています。耐久性はファイルシステム、ドライバー、ストレージ機器にも依存するため、実機で電源断を試験します。
ログと一時ファイルに別々の予算を与える
tmpfs は仮想メモリーを使い、swap が有効なら利用でき、アンマウントすると内容が失われます。バイト数と inode 数を制限し、その予算をピークメモリー試験に含めます。容量制限のない大きな RAM ログディレクトリは、それ以外は正常なアプリケーションのメモリーを使い果たす原因になります。
Systemd ベースのイメージでは、Storage=volatile によりジャーナルを /run/log/journal に保持し、永続モードでは利用可能な場合に /var/log/journal を使います。選んだモードに合わせて RuntimeMaxUse または SystemMaxUse を設定し、出荷版の journald 文書を参照します。BusyBox syslog には独自のサイズ、ローテーション、出力先設定が必要です。
大量の診断ログとは独立に、設定と更新のための空き容量を予約します。同じファイルシステム上のディレクトリを分けただけでは容量を隔離できません。適切なクォータ、パーティション、明示的な予約を使用します。どのイベントを電源断後も残すべきか定義し、認証情報を除去します。リモートログが有効なのは、切断、キュー増大、配送欠落への動作を定義した場合です。
永続化とロールバックを一緒に設計する
A/B ソフトウェアスロットがあっても、A/B アプリケーションデータが自動的に得られるわけではありません。新アプリケーションが共有データベースを旧版で読めない形式へ移行する場合があります。選択肢には、後方互換スキーマ、別々のデータ世代、明示的に試験した復元経路があります。RAUC のデータ保存ガイドは共有・冗長データパーティションを扱い、移行には製品固有の処理が必要だと説明しています。
更新のステージングが設定領域を使い切らないようにします。パッケージのダウンロード完了、検証完了、起動スロット選択、正常起動の確認を区別します。選択した更新フレームワークが必要とする状態だけを永続化します。工場出荷状態への初期化では、顧客設定、保持ログ、認証情報、機器識別情報のどれを消すかを文書で定めます。これらは異なる扱いを必要とすることが多いためです。
受入試験とトラブルシューティング
| 故障注入 | 定義すべき期待結果 | 最初に確認する証拠 |
|---|---|---|
| 設定確定処理中の電源断 | 有効な旧世代または新世代が残り、破損設定を黙って使わない | 設定検証、世代マーカー、ファイルシステムエラー |
| 永続ボリュームの欠落または破損 | 文書化した復旧動作 | マウントログ、機器識別、アプリケーション起動順序 |
| ログのバイト容量または inode 枯渇 | 設定と更新の方針を維持する | ファイルシステム容量、inode 使用量、ロガーエラー |
| 更新後のロールバック | 旧ソフトウェアが保持または復元されたデータを利用できる | スキーマ版と移行記録 |
| 一時ファイル大量使用後のコールドブート | メモリー予算内で実行時状態を再構築する | tmpfs の上限とピークメモリー記録 |
| 新 rootfs と既存オーバーレイの組み合わせ | 更新後の既定値とバイナリーが意図どおり見える | 上層ファイル、削除マーカー、移行方針 |
設定が消える場合は、まず書き込み先が永続領域であり、使用前にマウント済みか確認します。更新後も旧動作が残る場合は、オーバーレイによる隠蔽と保持設定を調べます。「読み取り専用ファイルシステム」と報告するサービスでは、ルート全体を読み書き可能に戻すのではなく、具体的な書き込み先を特定します。これらの試験には、管理された実験室での故障注入と合意済みの復旧手順が必要です。本文は電源断試験の結果を主張しません。
Obeita のファームウェア・BSP 診断サービスは、ストレージと起動のレビューに適した入口です。Linux/Qt HMI の納入事例は、関連する端末の背景を提供します。この事例は、本文の永続化アーキテクチャを検証した証拠ではありません。