このページの目次
一時ファイルシステムと擬似ファイルシステム
カバー範囲: procfs/sysfs/debugfs/tracefs → tmpfs (shmem) → devtmpfs → ramfs → kernfs フレームワーク → ファイルシステム実装方法 (擬似 vs 実在) カーネルバージョン: 2.6 ~ 6.x
概要
「擬似ファイルシステム」はデータをディスクに保存しません。データはカーネルによってアクセス時に動的に生成されます。最も一般的な例は、/proc(プロセス情報)、/sys(デバイスモデル)、/sys/kernel/debug(デバッグインターフェース)です。これらは通常のファイルのように見えますが、read() システムコールはディスク I/O ではなく、カーネル内のコールバック関数をトリガーします。
擬似ファイルシステムの核心的な価値は、統一された、ツールフレンドリーなインターフェースを提供することです。cat /proc/meminfo は、システムコール、ioctl、または特殊デバイスよりも直感的です。
procfs: プロセス情報
// fs/proc/
// 各プロセスの /proc/<pid>/ ディレクトリ:
// task_struct → proc_dir_entry → inode → dentry
// ファイルへのアクセス → proc 固有の read ハンドラをトリガー
// 例: /proc/<pid>/status
static const struct file_operations proc_status_operations = ;
// seq_file インターフェース (fs/seq_file.c):
// カーネルがテキスト出力を生成するための汎用フレームワークを簡素化
// バッファリング、ページング、シークを自動処理
// .start() / .next() / .stop() / .show()
// 実装: task_state() → seq_printf() で各フィールドを出力
// プロセスからは純粋なテキストファイルとして見えるが、内容はリアルタイムで生成される
主要な proc ファイル
// /proc/<pid>/maps: VMA リスト (mm->mmap をトラバース)
// /proc/<pid>/smaps: 各 VMA ごとの詳細なメモリ統計
// /proc/<pid>/fd/: 各 fd のシンボリックリンク → ファイルパス
// /proc/<pid>/attr/: セキュリティ属性 (SELinux/AppArmor)
// /proc/<pid>/mem: プロセスメモリへの読み書き (ptrace の代替)
sysfs: デバイスモデル
// fs/sysfs/
// sysfs は kernfs フレームワークベース (6.x+ でリファクタリング)
// 各 kobject → sysfs のディレクトリ/ファイル 1つ
// kernfs_node が sysfs の中核:
;
// sysfs 属性ファイル:
// .show(): cat /sys/... → テキストを生成
// .store(): echo xxx > /sys/... → パースして適用
// デバイスモデルのツリー構造:
// /sys/devices/ ← 実デバイスツリー
// /sys/bus/ ← バスタイプ → devices/ へのリンク
// /sys/class/ ← 機能別分類 → devices/ へのリンク
// /sys/block/ ← ブロックデバイス
debugfs / tracefs
// fs/debugfs/
// 非安定な API: 開発者向けのデバッグインターフェース
// 本番システムでは依存しないこと (内容/パスはバージョン間で変化する可能性がある)
struct dentry *;
// tracefs (fs/tracefs/):
// ftrace / tracepoints のマウントポイント
// /sys/kernel/tracing/ ← tracefs をマウント
// 旧来の /sys/kernel/debug/tracing (debugfs) の代替
tmpfs: メモリファイルシステム
// mm/shmem.c
// tmpfs = shmem ファイルシステム
// マウント: mount -t tmpfs tmpfs /tmp
// データはページキャッシュに保存される (匿名ページ + swap 対応)
// ディスクバックエンドなし → 電源断でデータ消失
// swap サポート: メモリ不足時にスワップへ書き出し
// 使用例:
// /tmp: 一時ファイル
// /dev/shm: POSIX 共有メモリ
// /run: デーモンの PID ファイルとソケット
// /var/run: 後方互換性のためのシンボリックリンク → /run
// 特徴:
// 自動拡張 (上限: size マウントオプション、または RAM の 50%)
// POSIX ACL、xattr、O_TMPFILE をサポート
devtmpfs
// drivers/base/devtmpfs.c
// /dev における動的デバイスノード管理
// カーネル起動時: devtmpfs をマウント → 既知のデバイス (例: /dev/sda, /dev/tty) を埋める
// デバイスホットプラグ: udev が uevent を受信 → デバイスノードの作成/削除
// devtmpfs は、早期起動段階 (udev がまだ実行されていない間) でさえも
// 基本的なデバイスノードが利用可能であることを保証する
// 2.6.32 以降のカーネルで自動処理
ramfs
// fs/ramfs/
// 極めてシンプルなメモリファイルシステム
// swap バッキングなし → データは常にメモリ上に存在
// サイズ制限なし → メモリ枯渇のリスクあり (危険!)
// inode 操作の複雑さなし → コードが最短
// ソースコードは約 200 行 (inode.c + file-mmu.c) のみ
// 主に特定用途 (initramfs 内部、rootfs) で使用
kernfs フレームワーク (6.x+)
// fs/kernfs/
// sysfs、cgroupfs の共有基盤
// 提供機能:
// 1. 階層的名前空間 (ディレクトリツリー)
// 2. ファイル操作 (read/write/mmap/poll)
// 3. シンボリックリンクとハードリンク
// 4. RCU 安全なトラバース
// なぜ kernfs が必要なのか?
// 旧来の sysfs と cgroupfs は独立して VFS グルーイングレイヤーを実装していた
// → コードの重複、個別のバグ
// kernfs が VFS 相互作用を統一 → 重複を削減し、信頼性を向上
擬似ファイルシステムの実装方法
案 1: seq_file (proc 内のテキスト出力用)
→ 適している: /proc/<pid>/status など、行単位で生成されるテキスト
案 2: kernfs (sysfs/cgroupfs 用)
→ 適している: 属性ファイル (.show/.store)、ツリー構造
案 3: debugfs (デバッグ用)
→ 適している: simple な file_operations の登録
案 4: libfs (簡易ファイルシステム)
→ 適している: ファイル数が少ない擬似ファイルシステム
→ fs/libfs.c: simple_fill_super(), simple_lookup_dir(), ...
→ 極めて少ないグルーイングコード
デバッグ
# proc ファイルシステムの統計
|
# sysfs デバイスツリー
# tmpfs の使用量
# カーネル内での debugfs の使用 (root が必要)
参考と拡張
- カーネルドキュメント:
Documentation/filesystems/proc.rst,Documentation/filesystems/sysfs.rst,Documentation/filesystems/tmpfs.rst,Documentation/filesystems/debugfs.rst - ソースコード:
fs/proc/— procfsfs/sysfs/— sysfsfs/kernfs/— kernfs フレームワークfs/debugfs/— debugfsmm/shmem.c— tmpfsdrivers/base/devtmpfs.c— devtmpfsfs/libfs.c— 簡易ファイルシステムツール
キーワード: procfs, sysfs, debugfs, tracefs, tmpfs, devtmpfs, kernfs, seq_file, 擬似ファイルシステム