![cat /proc/cpuinfo コマンドを実行すると何が起こりますか?](https://rvso.com/image/52103/cat%20%2Fproc%2Fcpuinfo%20%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E3%81%A8%E4%BD%95%E3%81%8C%E8%B5%B7%E3%81%93%E3%82%8A%E3%81%BE%E3%81%99%E3%81%8B%3F.png)
と書き込むと何が起こりますかcat /proc/cpuinfo
。これは、CPU 情報をオンザフライで読み取り、呼び出すたびにそのテキストを生成する OS への名前付きパイプ (または他の何か) ですか?
答え1
の下にあるファイルを読み込むたびに/proc
、カーネル内のコードが呼び出され、ファイルの内容として読み取るテキストが計算されます。内容がオンザフライで生成されるという事実は、ほとんどすべてのファイルの時間が現在として報告され、サイズが 0 として報告される理由を説明しています。ここで、0 は「不明」と読み替えてください。通常のファイルシステムとは異なり、 にマウントされているファイルシステムは/proc
、プロセス、ディスクや他のストレージメディア(FAT、ext2、zfsなど)やネットワーク(NFS、Sambaなど)からデータをロードせず、ユーザーコードも呼び出さない(ヒューズ)。
ProcfsはBSD以外のほとんどのUnixに存在します。1960年にAT&Tのベル研究所で誕生しました。UNIX 第 8 版プロセスに関する情報を報告する方法として (また、ps
を通じて読み取られた情報のプリティプリンタとしてもよく使用されます/proc
)。ほとんどの procfs 実装には、PID 123 のプロセスに関する情報を報告するために、と呼ばれるファイルまたはディレクトリがあります/proc/123
。Linux は、システムの状態を報告するエントリをさらに多く追加して proc ファイルシステムを拡張します。これには、あなたの例も含まれます/proc/cpuinfo
。
過去には、Linuxは/proc
ドライバーに関する情報を提供するさまざまなファイルを取得していましたが、この使用は現在では廃止され、/sys
、そして現在はゆっくりと進化しています。 やなど/proc
のエントリは下位互換性のためにそのまま残っていますが、より新しい同様のインターフェースは の下に作成されています。この回答では、Linux に焦点を当てます。/proc/bus
/proc/fs/ext4
/sys
/proc
Linuxに関するドキュメントの最初と 2 番目のエントリ ポイントは次のとおりです。
- の
proc(5)
マニュアルページ; - ファイル
/proc
システムの中にカーネルドキュメント。
3番目のエントリポイントは、ドキュメントに記載されていない場合、ソースを読むソースを自分のマシンにダウンロードすることもできますが、これは巨大なプログラムであり、ルクソールLinux の相互参照である は大きな助けになります。(LXR には多くのバリエーションがあり、 で実行されているものがlxr.linux.no
断然優れていますが、残念ながらサイトがダウンしていることがよくあります。) C の知識が少し必要ですが、謎の値を追跡するのにプログラマーである必要はありません。
/proc
エントリのコア処理はfs/proc
ディレクトリ。どのドライバもエントリを に登録できます/proc
(ただし、上記のように、これは に取って代わられ、現在は が推奨されています/sys
)。 で探しているものが見つからない場合はfs/proc
、他の場所を探してください。 ドライバは で宣言された関数を呼び出します。include/linux/proc_fs.h
カーネルバージョン最大3.9関数create_proc_entry
といくつかのラッパー(特にcreate_proc_read_entry
)とカーネルバージョンを提供する3.10以上代わりにproc_create
、およびproc_create_data
(およびさらにいくつか)のみを指定します。
たとえば/proc/cpuinfo
、検索すると、の呼び出し"cpuinfo"
につながります。proc_create("cpuinfo, …")
fs/proc/cpuinfo.c
コードはほぼ定型的なコードであることがわかります。ほとんどのファイルは/proc
テキストデータをダンプするだけなので、それを実行するためのヘルパー関数があります。seq_operations
構造、そして本当の肉はcpuinfo_op
データ構造はアーキテクチャに依存し、通常はarch/<architecture>/kernel/setup.c
(または別のファイルで)定義されます。x86を例にとると、arch/x86/kernel/cpu/proc.c
。ここでのメイン関数はshow_cpuinfo
、必要なファイル内容を印刷する です。残りのインフラストラクチャは、要求された速度で読み取りプロセスにデータを供給するためにあります。カーネル内のさまざまな変数のデータから、その場でデータが組み立てられているのがわかります。その中には、その場で計算されるいくつかの数値も含まれます。CPU周波数。
の大部分は/proc
プロセスごとの情報です/proc/<PID>
。これらのエントリはに登録されます。fs/proc/base.c
、 の中にtgid_base_stuff
配列; ここで登録されている関数の一部は他のファイルで定義されています。これらのエントリがどのように生成されるか、いくつかの例を見てみましょう。
cmdline
によって生成されるproc_pid_cmdline
同じファイル内にあります。プロセス内のデータを検索して出力します。clear_refs
は、これまで見てきたエントリとは異なり、書き込みは可能ですが、読み取りはできません。そのため、proc_clear_refs_operations
構造は定義するclear_refs_write
機能はありますが、読み取り機能はありません。cwd
はシンボリックリンク(少し魔法的なリンク)であり、proc_cwd_link
、 どれのプロセスの現在のディレクトリを検索するリンク コンテンツとして返します。fd
はサブディレクトリです。ディレクトリ自体に対する操作は、proc_fd_operations
データ構造(エントリを列挙する関数以外は定型的なものです)proc_readfd
(プロセスの開いているファイルを列挙する)エントリに対する操作が進行中である間、proc_fd_inode_operations は、。
のもう一つの重要な領域は/proc
、/proc/sys
への直接的なインターフェースであるsysctl
この階層のエントリから読み取ると、対応するsysctl値の値が返され、書き込むとsysctl値が設定されます。sysctlのエントリポイントは、fs/proc/proc_sysctl.c
Sysctlには独自の登録システムがあり、register_sysctl
と友達。
答え2
舞台裏でどんな魔法が起こっているのか知りたいときは、あなたの親友がいますstrace
。このツールの操作方法を学ぶことは、舞台裏でどんなクレイジーな魔法が起こっているのかをより深く理解するための最善の方法の 1 つです。
$ strace -s 200 -m strace.log cat /proc/cpuinfo
...
read(3, "processor\t: 0\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 37\nmodel name\t: Intel(R) Core(TM) i5 CPU M 560 @ 2.67GHz\nstepping\t: 5\nmicrocode\t: 0x4\ncpu MHz\t\t: 1199.000\ncache size\t: 3072 KB\nphy"..., 65536) = 3464
write(1, "processor\t: 0\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 37\nmodel name\t: Intel(R) Core(TM) i5 CPU M 560 @ 2.67GHz\nstepping\t: 5\nmicrocode\t: 0x4\ncpu MHz\t\t: 1199.000\ncache size\t: 3072 KB\nphy"..., 3464) = 3464
read(3, "", 65536) = 0
close(3) = 0
...
上記の出力から、これは/proc/cpuinfo
単なる通常のファイルである、または少なくともそのように見えることがわかります。それでは、さらに詳しく見ていきましょう。
より深いダイビング
#1- ls 付き。ファイル自体を見ると、「単なるファイル」のように見えます。
$ ls -l /proc/cpuinfo
-r--r--r--. 1 root root 0 Mar 26 22:45 /proc/cpuinfo
しかし、よく見てみましょう。これが特別なものであるという最初のヒントが得られます。ファイルのサイズが 0 バイトであることに注目してください。
#2- 統計付きここで を使用してファイルを見ると、stat
について何か特別なことがあるという次のヒントが得られます/proc/cpuinfo
。
$ stat /proc/cpuinfo
File: ‘/proc/cpuinfo’
Size: 0 Blocks: 0 IO Block: 1024 regular empty file
Device: 3h/3dInode: 4026532023 Links: 1
Access: (0444/-r--r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Context: system_u:object_r:proc_t:s0
Access: 2014-03-26 22:46:18.390753719 -0400
Modify: 2014-03-26 22:46:18.390753719 -0400
Change: 2014-03-26 22:46:18.390753719 -0400
Birth: -
実行 #2
$ stat /proc/cpuinfo
File: ‘/proc/cpuinfo’
Size: 0 Blocks: 0 IO Block: 1024 regular empty file
Device: 3h/3dInode: 4026532023 Links: 1
Access: (0444/-r--r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Context: system_u:object_r:proc_t:s0
Access: 2014-03-26 22:46:19.945753704 -0400
Modify: 2014-03-26 22:46:19.945753704 -0400
Change: 2014-03-26 22:46:19.945753704 -0400
Birth: -
アクセス、変更、変更の時刻に気付きましたか? これらはアクセスごとに変化し続けます。3 つすべてがこのように変化するのは非常に珍しいことです。編集されない限り、ファイルのタイムスタンプ属性は通常同じままです。
#3- ファイル付き。このファイルが通常のファイルではないことを示すもう 1 つの手がかり:
$ file /proc/cpuinfo
/proc/cpuinfo: empty
名前付きパイプの何らかの表現である場合、次のいずれかのファイルのように表示されます。
$ ls -l /dev/initctl /dev/zero
prw-------. 1 root root 0 Mar 26 20:09 /dev/initctl
crw-rw-rw-. 1 root root 1, 5 Mar 27 00:39 /dev/zero
$ file /dev/initctl /dev/zero
/dev/initctl: fifo (named pipe)
/dev/zero: character special
に触れるとemptyfile
、/proc/cpuinfo
パイプというよりはファイルのように見えます。
$ touch emptyfile
$ ls -l emptyfile
-rw-rw-r--. 1 saml saml 0 Mar 27 07:40 emptyfile
$ file emptyfile
emptyfile: empty
#4- マウント付き。
そこで、この時点で一歩下がって少しズームアウトする必要があります。特定のファイルを見ていますが、おそらくこのファイルが存在するファイルシステムを見る必要があるでしょう。そのためには、 コマンドを使用できますmount
。
$ mount | grep " /proc "
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
わかりました。ファイルシステムの種類は ですproc
。 は/proc
異なるファイルシステムの種類です。これは、その下のファイル/proc
が特別であるというヒントです。これらは、ありふれたファイルではありません。それでは、ファイルシステムを特別なものにしているものについて、さらに情報を調べてみましょうproc
。
mount
のマニュアルページを見てみましょう:
proc ファイルシステムは特別なデバイスに関連付けられておらず、マウントするときに、デバイス指定の代わりに proc などの任意のキーワードを使用できます。(慣例的に none を選択すると、あまり良い結果にはなりません。umount からのエラー メッセージ「none busy」がわかりにくくなる場合があります。)
proc
のマニュアルページを見てみましょう:
proc ファイル システムは、カーネル データ構造へのインターフェイスとして使用される疑似ファイル システムです。通常は /proc にマウントされます。そのほとんどは読み取り専用ですが、一部のファイルではカーネル変数を変更できます。
同じマニュアルページの少し下には、次の記述があります。
/proc/CPU情報
これは CPU とシステム アーキテクチャに依存する項目のコレクションで、サポートされているアーキテクチャごとにリストが異なります。2 つの一般的なエントリは、CPU 番号を示すプロセッサと、カーネルの初期化中に計算されるシステム定数である bogomips です。SMP マシンには各 CPU の情報があります。lscpu(1) コマンドはこのファイルから情報を収集します。
マニュアル ページの下部には、次のタイトルのカーネル ドキュメントへの参照があります。/proc ファイルシステムその文書から引用すると:
proc ファイル システムは、カーネル内の内部データ構造へのインターフェイスとして機能します。システムに関する情報を取得したり、実行時に特定のカーネル パラメータを変更したりするために使用できます (sysctl)。
結論
では、ここで何を学んだでしょうか?/proc
疑似ファイルシステムとも呼ばれ、「内部データ構造へのインターフェース」でもあることから、その中の項目はない実際のファイルではなく、ファイルのように見えるように作成された単なる表現であり、実際にはファイルではありません。
最後に、2004 年頃の以前のバージョンに含まれていたと思われるこの引用文を引用します。 man 5 proc
しかし、何らかの理由で現在は含まれていません。注記:何が何であるかを非常にうまく説明しているので、なぜ削除されたのかわかりません/proc
。
GNU/Linux システムの /proc ディレクトリは、カーネルへのファイルシステムのようなインターフェースを提供します。これにより、アプリケーションとユーザーは、通常のファイルシステム I/O 操作を使用してカーネルから情報を取得したり、カーネルに値を設定したりすることができます。
proc ファイル システムは、プロセス情報疑似ファイル システムと呼ばれることもあります。このファイルには ``実際の'' ファイルではなく、ランタイム システム情報 (システム メモリ、マウントされているデバイス、ハードウェア構成など) が含まれます。このため、proc ファイル システムはカーネルの制御および情報センターとみなすことができます。実際、多くのシステム ユーティリティは、このディレクトリ内のファイルへの呼び出しにすぎません。たとえば、カーネルによってロードされたモジュールを一覧表示するコマンド lsmod は、基本的に 'cat /proc/modules' と同じですが、システムの PCI バスに接続されているデバイスを一覧表示する lspci は 'cat /proc/pci' と同じです。このディレクトリにあるファイルを変更することで、システムの実行中にカーネル パラメータを変更できます。
ソース: proc疑似ファイルシステム
参考文献
答え3
@slm の回答は非常に包括的ですが、視点を変えるとより簡単な説明が生まれるのではないかと思います。
日常的な使用では、ファイルを物理的なもの、つまりデバイスに保存されたデータの塊として考えることができます。これにより、/proc/cpuinfoのようなファイルは非常に神秘的でわかりにくいものになります。しかし、ファイルを次のように考えれば、すべてが完全に理解できます。インターフェース; プログラムとの間でデータを送受信する方法。
このようにデータを送受信するプログラムはファイルシステムまたはドライバーです(これらの用語をどのように定義するかによって、定義が広すぎたり狭すぎたりする可能性があります)。重要な点は、いくつかのこれらのプログラムの多くは、このインターフェースを介して送信されたデータを保存および取得するためにハードウェア デバイスを使用しますが、すべてではありません。
ファイルシステムの例しないストレージデバイスを(少なくとも直接)使用するものは次のとおりです。
- 検索または計算されたデータを使用するファイルシステム。Proc はさまざまなカーネル モジュールからデータを取得するため、その一例です。極端な例としては πfs ( github.com/philipl/pifs ) があります。
- 通常のユーザー空間プログラムでデータを処理するすべてのFUSEファイルシステム
- 暗号化、圧縮、オーディオトランスコーディングなどを使用して、別のファイルシステムのデータをオンザフライで変換するファイルシステム ( khenriks.github.io/mp3fs/ )
Plan9 OS (http://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs) は、ファイルを一般的なプログラミング インターフェイスとして使用する極端な例です。