/ proc / *はどのように機能しますか?


62

中に多くのファイルがある/procような、/proc/cpuinfo/proc/meminfo/proc/devicesというように、これは、開かれた、リターンシステム情報が。

これらのファイルを実行してもfile空であることがわかるだけなので、これらのファイルは実際には存在していないようです。

$ file /proc/cpuinfo
/proc/cpuinfo: empty

これらのファイルは正確にどのように機能しますか?

回答:


72

少なくとも実装の詳細が必要ない場合は、実際には非常に簡単です。

まず、Linuxでは、すべてのファイルシステム(ext2、ext3、btrfs、reiserfs、tmpfs、zfs、...)がカーネルに実装されています。FUSEを介してユーザーランドコードの作業をオフロードするものもあれば、カーネルモジュールの形式でのみ提供されるものもあります(ネイティブZFSはライセンスの制限により後者の顕著な例です)が、どちらの場合もカーネルコンポーネントが残っています。これは重要な基本です。

プログラムがファイルから読みたい場合は、それが最終的にの形でカーネルで終わる様々なシステムライブラリの呼び出しを発行しますopen()read()close()シーケンスが(おそらくとseek()良い測定のためで投げ)。カーネルは提供されたパスとファイル名を取得し、ファイルシステムおよびデバイスI / Oレイヤーを介して、これらを物理ストレージへの物理的な読み取り要求(および多くの場合、書き込み要求-atime更新など)に変換します。

ただし、これらの要求を特に物理的な永続ストレージに変換する必要はありません。カーネルの契約では、システムコールの特定のセットを発行すると、問題のファイルの内容提供されます。私たちの物理的な領域で正確に「ファイル」が存在する場所は、これに次ぐものです。

上は/proc通常として知られているものを装着されていますprocfs。これは特殊なファイルシステムタイプですが、ファイルシステムであるため、実際にext3どこかにマウントされたファイルシステムなどと違いはありません。そのため、要求はprocfsファイルシステムドライバーコードに渡されます。このコードは、これらすべてのファイルとディレクトリを認識し、カーネルデータ構造から特定の情報を返します

この場合の「ストレージレイヤー」はカーネルデータ構造でありprocfs、それらにアクセスするためのクリーンで便利なインターフェイスを提供します。procfsのマウント/procは単なる慣習であることに注意してください。他の場所に簡単にマウントできます。実際、たとえば、そこで実行されているプロセスが何らかの理由で/ procにアクセスする必要がある場合、chroot jailなどで行われます。

何らかのファイルに値を書き込む場合も同じように機能します。カーネルレベルで、それは一連の変換open()seek()write()close()再びファイルシステムドライバに渡されます呼び出します。この場合も、procfsコードです。

file返される特定の理由emptyは、procfsによって公開されるファイルの多くが0バイトのサイズで公開されるためです0バイトサイズはカーネル側の最適化である可能性があります(/ procの多くのファイルは動的であり、読み取りごとに長さを簡単に変えることができ、読み取りごとにディレクトリごとに各ファイルの長さを計算します潜在的に非常に高価です)。この回答へのコメントで行くと、straceまたは同様のツールを実行して独自のシステムで確認でき、file最初にstat()特別なファイルを検出するための呼び出しを発行し、次にファイルサイズが0と報告された場合に機会を取ります、中止し、ファイルが空であることを報告します。

この動作は、実際に文書化されているとすることができます指定することで上書き-sまたは--special-filesfile、呼び出しなどの副作用を有することができるマニュアルページに記載されたものの。以下の引用は、2011年10月17日付のBSDファイル5.11のマニュアルページからのものです。

通常、fileは、stat(2)が通常のファイルであると報告する引数ファイルのタイプの読み取りと判別のみを試みます。これにより、特殊ファイルの読み取りに特有の結果が生じる可能性があるため、問題が防止されます。この-sオプションを指定すると、ファイルは、ブロックまたは文字の特殊ファイルである引数ファイルも読み取ります。これは、ブロックスペシャルファイルであるrawディスクパーティション内のデータのファイルシステムタイプを判別するのに役立ちます。 一部のシステムではrawディスクパーティションのサイズがゼロと報告されるため、このオプションは、stat(2)によって報告されるファイルサイズを無視します


5
strace file /proc/versionまたはltrace -S /proc/versionで見ると、最適化はかなり小さいです。それはありませんstat()最初の呼び出しを、大きさは、このようにスキップし、0であることを見つけたopen()-しかし、その前に、それはいくつかの魔法のファイルをロードしています。
ott--

2
@ ott--それは確かに奇妙な一連のイベントですが、複数のファイル名をに渡すことができるという事実に関連している可能性がありますfile。この方法では、ファイルはマジックファイルをプリロードし、パラメーターごとにコマンドラインパラメーターを処理します。マジックファイルの読み込みをコードの「この特定のファイルがどのような種類のファイルであるかを判断する直前に行う」ように移動するのではなく、複雑さが増します。stat()その戻り値を呼び出して動作することは、本質的に無害です。バグを導入する追加の内部状態リスクを追跡する複雑さを追加します。
CVn

@ ott--実際、file「ファイルが空です」と報告される理由は、stat特別なファイル(名前付きパイプ、デバイスなど)を検出するために呼び出し、空のファイルの処理を停止するためです。file -s /proc/version「ASCIIテキスト」を報告します。
ジル 'SO-悪であるのをやめる'

4
@Gilles -sは、block / char特殊デバイス用です。最後に私が見fileたソース、およびfsmagic.cの終わりに、私はそれを返し、なぜこの説明を見たASCII textの代わりにemptyIf stat() tells us the file has zero length, report here that the file is empty, so we can skip all the work of opening and reading the file. But if the -s option has been given, we skip this optimization, since on some systems, stat() reports zero size for raw disk partitions.
ott--

15

このディレクトリでは、カーネルがデバイスを表示する方法を制御し、カーネル設定を調整し、デバイスをカーネルに追加して、それらを再度削除できます。このディレクトリでは、メモリ使用量とI / O統計直接表示できます。

マウントされているディスクと使用されているファイルシステムを確認できます。要するに、あなたが何を探すべきかを知っていれば、Linuxシステムのあらゆる側面をこのディレクトリから調べることができます。

/procディレクトリは通常のディレクトリではありません。ブートCDから起動し、ハードドライブ上のそのディレクトリを見ると、空であることがわかります。通常の実行中のシステムで見ると、かなり大きくなる可能性があります。ただし、ハードディスク領域を使用していないようです。これは、仮想ファイルシステムであるためです。

ので/proc、ファイルシステムは仮想ファイルシステムであり、メモリに常駐し、新しい/procファイルシステムは、Linuxマシンを再起動するたびに作成されます。

言い換えれば、ファイルおよびディレクトリタイプのインターフェイスを介してLinuxシステムの根幹を簡単に覗き見する手段にすぎません。/procディレクトリ内のファイルを見ると、Linuxカーネル内のある範囲のメモリを直接見ていて、何が見えるかを確認しています。

ファイルシステムのレイヤー

ここに画像の説明を入力してください

例:

  • 内部/procには、プロセスIDで名前が付けられた実行中の各プロセスのディレクトリがあります。これらのディレクトリには、次のようなプロセスに関する有用な情報を持つファイルが含まれています。
    • exe:プロセスが開始されたディスク上のファイルへのシンボリックリンクです。
    • cwd:プロセスの作業ディレクトリへのシンボリックリンクです。
    • wchan:読み取り時に、プロセスが実行されている待機チャネルを返します。
    • maps:読み取り時に、プロセスのメモリマップを返します。
  • /proc/uptime スペースで区切られた秒単位の2つの10進数値として稼働時間を返します。
    • カーネルが開始されてからの時間。
    • カーネルがアイドル状態であった時間。
  • /proc/interrupts:割り込みに関連する情報。
  • /proc/modules:モジュールのリスト。

詳細については、man procまたはkernel.orgを参照してください。


「ブートCDから起動して、ハードドライブ上のそのディレクトリを見ると、空であることがわかります。」これは/ procに固有のものではなく、基礎となるファイルシステムがマウントされていないマウントポイントに一般的です。同じブートCDから起動してのような操作mount -t procfs procfs /mnt/procを行うと、現在実行中のカーネルの/ procが表示されます。
CVn

5

あなたは正しい、彼らは実際のファイルではありません。

簡単に言えば、カーネルを直接呼び出すのではなく、ファイルを読み書きする通常の方法を使用してカーネルと対話する方法です。これは、Unixの「すべてがファイルである」という哲学に沿っています。

ファイル/procは物理的にどこにも存在しませんが、カーネルはその中で読み書きするファイルに反応し、ストレージに書き込む代わりに、情報を報告したり、何かを実行します。

同様に、のファイル/devは実際には従来の意味のファイルではありません(一部のシステムでは、ファイル/devが実際にディスク上に存在する場合がありますが、参照するデバイス以外にはあまりありません)-彼らは話すことができます通常のUnixファイルI / O APIを使用するデバイス、またはシェルなど、それを使用するデバイス


1
* nixに似ているのは、ファイルのみを保護できることです。アクセス制御リストはファイルシステムに保持されるため、ファイルシステムドライバーによって既に提供されている共通のメカニズムを使用して特権リソースを保護すると便利です。これにより、カーネル構造にアクセスするツールの実装が簡略化され、代わりにprocファイルシステムの仮想ファイルから読み取ることで、権限を高めずに実行できるようになります。
ペッカ

3

/procディレクトリ内には、2種類のコンテンツがあります。最初の番号が付けられたディレクトリと2番目のコンテンツはシステム情報ファイルです。

/proc仮想ファイルシステムです。たとえば、を実行ls -l /proc/statすると、サイズが0バイトであることがわかりますが、「cat / proc / stat」を実行すると、ファイル内にコンテンツが表示されます。

ls -l /procを実行すると、数字だけのディレクトリがたくさん表示されます。これらの番号はプロセスID(PID)を表します。この番号付きディレクトリ内のファイルは、その特定のPIDを持つプロセスに対応しています。

で利用できるいくつかのファイルには/proc、cpuinfo、meminfo、loadavgなどのシステム情報が含まれています。

一部のLinuxコマンドは、これらの/procファイルから情報を読み取り、表示します。たとえば、freeコマンドは、/proc/meminfoファイルからメモリ情報を読み取り、フォーマットして表示します。

個々の/procファイルの詳細については、「man 5 FILENAME」を実行してください。

/proc/cmdline – Kernel command line
/proc/cpuinfo – Information about the processors.
/proc/devices – List of device drivers configured into the currently running kernel.
/proc/dma – Shows which DMA channels are being used at the moment.
/proc/fb – Frame Buffer devices.
/proc/filesystems – File systems supported by the kernel.
/proc/interrupts – Number of interrupts per IRQ on architecture.
/proc/iomem – This file shows the current map of the system’s memory for its various devices
/proc/ioports – provides a list of currently registered port regions used for input or output communication with a device
/proc/loadavg – Contains load average of the system
The first three columns measure CPU utilization of the last 1, 5, and 10 minute periods.
The fourth column shows the number of currently running processes and the total number of processes.
The last column displays the last process ID used.
/proc/locks – Displays the files currently locked by the kernel
Sample line:
1: POSIX ADVISORY WRITE 14375 08:03:114727 0 EOF
/proc/meminfo – Current utilization of primary memory on the system
/proc/misc – This file lists miscellaneous drivers registered on the miscellaneous major device, which is number 10
/proc/modules – Displays a list of all modules that have been loaded by the system
/proc/mounts – This file provides a quick list of all mounts in use by the system
/proc/partitions – Very detailed information on the various partitions currently available to the system
/proc/pci – Full listing of every PCI device on your system
/proc/stat – Keeps track of a variety of different statistics about the system since it was last restarted
/proc/swap – Measures swap space and its utilization
/proc/uptime – Contains information about uptime of the system
/proc/version – Version of the Linux kernel, gcc, name of the Linux flavor installed.

2
これは、「/ procにあるものを使用する方法」に似ています。「/ procの仕組み」ではなく。有用な情報ですが、必ずしもこの特定の質問に答えているわけではありません。
13:30

/ proc内の各ファイルはランタイム情報です。つまり、カーネルの/ proc / meminfo部分をcatすると、ファイルの内容を生成する機能が実行されます。
シャイレッシュ

3

最小限の実行可能な例

私の意見でこれらのことを理解する最良の方法は、実際にそれらをいじることです。そこで、procfsエントリを作成するカーネルモジュールを次に示します。

myprocfs.c

#include <linux/debugfs.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h> /* seq_read, seq_lseek, single_open, single_release */
#include <uapi/linux/stat.h> /* S_IRUSR */

static const char *filename = "lkmc_procfs";

static int show(struct seq_file *m, void *v)
{
    seq_printf(m, "abcd\n");
    return 0;
}

static int open(struct inode *inode, struct  file *file)
{
    return single_open(file, show, NULL);
}

static const struct file_operations fops = {
    .llseek = seq_lseek,
    .open = open,
    .owner = THIS_MODULE,
    .read = seq_read,
    .release = single_release,
};

static int myinit(void)
{
    proc_create(filename, 0, NULL, &fops);
    return 0;
}

static void myexit(void)
{
    remove_proc_entry(filename, NULL);
}

module_init(myinit)
module_exit(myexit)
MODULE_LICENSE("GPL");

そして、次のように対話します。

insmod procfs.ko
cat /proc/lkmc_procfs

そして、それは出力を生成します:

abcd

この例から、procファイルを使用するとopenreadやなどの任意の「ファイル関連システムコール」を実装できることがわかりますllseek

これらのシステムコールは、カーネルとの任意の通信に使用できます。

したがって、これらのファイルは、ファイルシステム内の実際のファイルとは関係ありません。ほとんどすべてのファイルに当てはまります。

たとえば、小さな例では、read常にを返す役に立たないファイルを作成しますabcd\n

以下は、このカーネルモジュールを簡単かつ安全にビルドしてプレイするための、完全に自動化されたQEMU + Buildrootセットアップです。

他のいくつかの同様のインターフェイスは次のとおりです。

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