コマンドcat / proc / cpuinfoを実行するとどうなりますか?


回答:


72

でファイルを読み取るたび/procに、カーネルでコードを呼び出して、ファイルの内容として読み取るテキストを計算します。コンテンツがオンザフライで生成されるという事実は、ほとんどすべてのファイルの時間が現在として報告され、サイズが0として報告される理由を説明します。ここでは0を「わからない」と読む必要があります。通常のファイルシステムとは異なり、にマウントされ/procているprocfsと呼ばれるファイルシステムは、ディスクまたは他のストレージメディア(FAT、ext2、zfsなど)またはネットワーク(NFS、Sambaなど)からデータをロードしません。ユーザーコードを呼び出しません(FUSEとは異なります)。

Procfsは、ほとんどの非BSDユニックスに存在します。UNIXに関する第8版のAT&TのBell Labsで、プロセスに関する情報を報告する方法として始まりました(ps多くの場合、情報を読み通すためのきれいなプリンターです/proc)。ほとんどのprocfs実装には、/proc/123PID 123のプロセスに関する情報を報告するために呼び出されるファイルまたはディレクトリがあります。Linuxは、例を含むシステムの状態を報告するさらに多くのエントリでprocファイルシステムを拡張します/proc/cpuinfo

過去に、Linux /procはドライバーに関する情報を提供するさまざまなファイルを取得していましたが、この使用は現在では廃止され/sys/proc現在では徐々に進化しています。以下のようなエントリ/proc/busとは、/proc/fs/ext4それらが下位互換性のためであるが、新しい同様のインターフェースを下に作成される残ります/sys。この回答では、Linuxに焦点を当てます。

/procLinux に関するドキュメントの最初と2番目のエントリポイントは次のとおりです。

  1. proc(5)manページ
  2. /procファイルシステムでのカーネルのドキュメント

3番目のエントリポイントは、ドキュメントで説明されていない場合、ソースを読んでいます。マシンにソースをダウンロードできますが、これは巨大なプログラムであり、Linuxの相互参照であるLXRは大きな助けになります。(LXRには多くのバリアントがあります。実行中のバリアントがlxr.linux.noはるかに優れていますが、残念ながらサイトがダウンしていることがよくあります。)Cの少しの知識が必要ですが、神秘的な値を追跡するためにプログラマである必要はありません。

/procエントリのコア処理はfs/procディレクトリにあります。どのドライバーでもエントリを登録できます/proc(上記のように、これはの代わりに推奨されなくなりました/sysfs/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.ctgid_base_stuff配列に登録されています。ここで登録されている一部の関数は、他のファイルで定義されています。これらのエントリが生成される方法の例をいくつか見てみましょう。

  • cmdlineproc_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友人や友人との独自の登録システムがあります。


59

あなたの親友が舞台裏でどんな魔法が起きているのかを見抜くとき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つのファイルのように見えることがわかります。深く掘り下げましょう。

より深いダイビング

#1 -ls ..で

ファイル自体を見ると、「単なるファイル」のように見えます。

$ ls -l /proc/cpuinfo 
-r--r--r--. 1 root root 0 Mar 26 22:45 /proc/cpuinfo

しかし、よく見てください。ファイルのサイズが0バイトであることに注意してください。

#2-統計情報付き

を使用してファイルを見ると、stat何か特別なものがあるという次のヒントを得ることができます/proc/cpuinfo

実行#1
$ 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-ファイル付き..

このファイルが通常のファイル以外のものであるという別の手がかり:

$ 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)

OK、ファイルシステムのタイプはtype procです。/proc異なるファイルシステムのタイプも同様です。これは、下にあるファイル/procが特別であるというヒントです。それらは、あなたのミルファイルの実行だけではありません。それでは、procファイルシステムを特別なものにするための詳細情報を見つけましょう。

見撮影mountのmanページを:

procファイルシステムは特別なデバイスに関連付けられていないため、マウントするときに、デバイス仕様の代わりにprocなどの任意のキーワードを使用できます。(慣習的な選択肢noneはそれほど幸運ではありません:umountからの「none busy」というエラーメッセージは混乱を招く可能性があります。)

そして、procのmanページを見ると:

procファイルシステムは、カーネルデータ構造へのインターフェイスとして使用される擬似ファイルシステムです。通常、/ procにマウントされます。ほとんどは読み取り専用ですが、一部のファイルではカーネル変数を変更できます。

同じmanページのもう少し下の部分:

/ proc / cpuinfo

これは、CPUおよびシステムアーキテクチャに依存する項目のコレクションであり、サポートされる各アーキテクチャごとに異なるリストがあります。2つの一般的なエントリは、CPU番号とbogomipsを提供するプロセッサです。カーネルの初期化中に計算されるシステム定数。SMPマシンには、各CPUの情報があります。lscpu(1)コマンドは、このファイルから情報を収集します。

マニュアルページの下部には、ここで見つけることができるカーネル文書への参照があります。タイトルは/ proc FILESYSTEMです。その文書からの引用:

procファイルシステムは、カーネルの内部データ構造へのインターフェイスとして機能します。システムに関する情報を取得し、実行時に特定のカーネルパラメータを変更するために使用できます(sysctl)。

結論

ここで何を学びましたか?まあその与えられた/proc疑似ファイルシステムとも、「内部データ構造へのインタフェース」と呼ばれ、それはその中の項目があると仮定するのはおそらく安全ですではない実際のファイルではなく、ただ症状は、ファイルのように見えるように作られたが、実際にはありません。

この引用は、man 5 proc2004年頃の以前のバージョンに 含まれていたようですが、何らかの理由で含まれなくなりました。注:それが何であるかを非常にうまく説明しているため、なぜ削除されたのかわかりません/proc

GNU / Linuxシステムの/ procディレクトリは、カーネルへのインターフェースのようなファイルシステムを提供します。これにより、アプリケーションとユーザーは、通常のファイルシステムI / O操作を使用して、カーネルから情報を取得し、カーネルの値を設定できます。

procファイルシステムは、プロセス情報擬似ファイルシステムと呼ばれることもあります。「実際の」ファイルではなく、ランタイムシステム情報(システムメモリ、マウントされたデバイス、ハードウェア構成など)が含まれます。このため、カーネルの制御および情報センターと見なすことができます。実際、非常に多くのシステムユーティリティは、このディレクトリ内のファイルへの呼び出しにすぎません。たとえば、カーネルによってロードされたモジュールをリストするコマンドlsmodは基本的に「cat / proc / modules」と同じですが、システムのPCIバスに接続されているデバイスをリストするlspciは「cat / proc proc / pci '。このディレクトリにあるファイルを変更することにより、システムの実行中にカーネルパラメーターを変更できます。

ソース: proc疑似ファイルシステム

参照資料


1
クール、:)これは私が質問を見たように、私が試した最初の事はある:strace -o catcpuproc.txt cat /proc/cpuinfo
MKC

1
素敵な答え!Linuxでは、さらに深く掘り下げたい場合、procファイルシステムのソースはカーネルソースのfs / procにあります。fs / proc / cpuinfo.cがあることがわかりますが、残念ながら、アーキテクチャに依存するため、大規模なリフティングがarch /全体に分散しているため、かなり空です。より簡単な例については、fs / proc / uptime.cを参照してください。ファイルを一見することで、uptime_proc_showが必要なデータを取得する主な要因であると推測できます。また、呼び出す関数を詳しく調べることで、さらに詳しく調べることができます。seq_fileインターフェイスを理解し、それはprocfsのに使用されている方法を確認するには:
スティーブン・D


1
@slm:+1、素晴らしい答え。しかし、私にとって、それが特別なファイルである最初のヒントはサイズ^^ 0バイトですが、そこからたくさんのものを猫にすることができます(いくつかのパイプファイルに似ています)。
オリビエデュラック14年

@OlivierDulac-良い点。フィードバックに基づいて追加の編集を行いました。LMKは、さらに改善できる場合。ありがとう。
slm

14

@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)は、一般的なプログラミングインターフェイスとしてファイルを使用する極端な例です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.