PK
パーネルカニック研究所
今日もどこかでkernel panic。
root@pk-lab:~#

「/proc」ディレクトリ:Linuxの生きた心臓部を覗く窓

連載ナビ

この連載は「Linuxを使えるようになる」ではなく、「Linuxがどう動いているのか」を理解するための実践シリーズです。

今回は Linuxを理解する 〜 LFSで学ぶLinux内部構造 〜 の Part 2 / 第2回として、仕組みのつながりを意識しながら学びます。

—

/procは、カーネルの内部状態をファイルに見せかけた「窓口」

前回、/proc は「ディスク上に実体がない特別なディレクトリ」だと紹介しました。今回はその正体を明らかにします。

結論から言うと、/proc は procfs という仮想ファイルシステムで、Linuxカーネルが自身の内部状態(メモリ、CPU、プロセスの情報)を、読み出された瞬間にメモリ上で生成してファイルの形で見せているものです。cat /proc/meminfo と打ったとき、ディスクからファイルが読まれているのではなく、カーネルが「今この瞬間のメモリ状況」をその場でテキストに整形して返しています。

実体がないことは、マウント情報で確認できます。


mount | grep /proc
# proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)

type proc とあるとおり、ext4のようなディスク上のファイルシステムではなく、カーネルが提供する専用のファイルシステムです。

「すべてはファイル」だから、専用ツールなしで調査できる

なぜカーネルはわざわざ内部状態を「ファイル」として見せるのでしょうか。理由は、UNIX/Linuxの設計原則である "Everything is a file"(すべてはファイルである) にあります。

情報をファイルという統一インターフェースで公開しておけば、カーネルの状態を調べるのに専用のAPIやツールは不要になります。cat で読み、grep で絞り込み、シェルスクリプトで加工する——普段ファイルに対して使っている道具が、そのままカーネルの調査に使えます。

実際、ps や top や free といったお馴染みのコマンドは、内部で /proc を読んで整形表示しているだけです。たとえば free はメモリ情報の表示に /proc/meminfo を使っています。つまり /proc を直接読むことは、ツール越しの二次情報ではなく、カーネルが出す一次情報にあたる行為です。ツールの表示が信じられないとき、ツールが入っていない最小構成のコンテナの中にいるとき、この知識が効きます。

システム全体の状態を読む: cpuinfo・meminfo・loadavg

/proc 直下のファイルは、システム全体の状態を表します。代表的なものを実際の読み方とセットで押さえましょう。

  • /proc/cpuinfo — CPUのモデル名、コア数、フラグ(対応命令セット)。論理コア数を数えたいときは grep -c processor /proc/cpuinfo が定番です。
  • /proc/meminfo — メモリの内訳。先頭の MemTotal(搭載量)、MemFree(完全な空き)、MemAvailable(キャッシュ解放分も含めた実質的な利用可能量)の区別が重要で、「MemFreeが少ない=メモリ不足」ではありません。
  • /proc/loadavg — ロードアベレージ。出力は次のような1行です。

0.52 0.58 0.59 2/1234 5678

左から「直近1分・5分・15分の平均負荷」「実行中プロセス数/全プロセス数」「最後に作られたPID」です。CPUコア数を超える値が続いていれば、処理待ちが発生していると判断できます。

  • /proc/version — 動作中のカーネルのバージョンとビルド情報。uname -r の情報源に相当します。

プロセスごとの状態を読む: /proc/[PID] の中身

/proc の中に並ぶ数字だけのディレクトリ(/proc/1、/proc/2345 など)は、その番号のPIDを持つプロセス1つ1つに対応しています。/proc/1 は起動後最初のプロセス(次々回に扱うPID 1)です。よく使うのは次の4つです。

  • /proc/[PID]/status — プロセス名、状態(Running/Sleepingなど)、親プロセスID(PPid)、メモリ使用量(VmRSS)が人間に読みやすい形式で並びます。
  • /proc/[PID]/cmdline — そのプロセスの起動コマンドラインです。
  • /proc/[PID]/fd/ — そのプロセスが開いているファイルディスクリプタの一覧。Too many open files というエラーの調査では、ここの個数を数えるのが直接的な手段です。
  • /proc/self — 「このファイルを読んでいるプロセス自身」を指すシンボリックリンク。cat /proc/self/status を実行すると、その cat 自身の情報が表示されます。

実践例として、「Webサーバーの応答が遅い」ときの調査手順を /proc ベースで組むとこうなります。


# 1. システム全体が過負荷でないか確認
cat /proc/loadavg

# 2. nginxのPIDを特定(例として2345とする)
pidof nginx

# 3. プロセスの状態を確認(State行がR/S/Zのどれか)
grep -E 'State|VmRSS' /proc/2345/status

# 4. 開いているファイルディスクリプタ数を確認
ls /proc/2345/fd | wc -l

ps や lsof が使えない環境でも、/proc さえ読めればここまで調査できます。

一次情報を読めることが、ツールに頼らない強さになる

/proc はディスク上に実体を持たない仮想ファイルシステムで、カーネルの内部状態を「ファイル」という統一インターフェースで公開している——これが今回の結論です。ps や top はこの一次情報の整形役に過ぎず、/proc を直接読めるエンジニアは、ツールが使えない環境でも調査を進められます。

ところで今回、「数字のディレクトリ=プロセス」と何度も書きましたが、そもそもプロセスとは正確には何なのでしょうか。次回は、プログラムとプロセスの違い、そしてプロセスが生まれて消えるまでの仕組みを掘り下げます。

コマンドで/procを探検する


# CPUの情報を確認する
head -n 10 /proc/cpuinfo

# メモリの使用状況を確認する(MemAvailableに注目)
head -n 5 /proc/meminfo

# ロードアベレージを確認する
cat /proc/loadavg

# 自分自身のプロセス情報を確認する
head -n 10 /proc/self/status

チェックポイント

  • /proc ディレクトリがディスク上に実在するものではないことを説明できる
  • cat /proc/meminfo を実行し、MemTotal(総メモリ量)の値を見つけられる
  • /proc/loadavg の先頭3つの数値が何を意味するか言える
  • ps コマンドが、/proc 配下の情報を利用していることを理解した

今回理解できたこと

  • /proc は、カーネルの現在の状態をファイルとして見せるための仮想ファイルシステム(procfs)であること
  • システム全体の統計情報(cpuinfo・meminfo・loadavg)と、プロセスごとの詳細情報(/proc/[PID])が読めること
  • "Everything is a file" の設計により、cat や grep だけでカーネルの一次情報にアクセスできること
  • top や ps といったコマンドは、/proc の情報を整形して表示しているに過ぎないこと