web-dev-qa-db-ja.com

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

/procには、/proc/cpuinfo/proc/meminfo/proc/devicesなどの多くのファイルがあり、開くとシステム情報が返されます。

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

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

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

65
user2064000

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

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

プログラムがファイルから読み取る場合、最終的にはopen()read()close()シーケンスの形でカーネルに到達するさまざまなシステムライブラリコールが発行されます。 (おそらくseek()が適切な量のためにスローされます)。カーネルは提供されたパスとファイル名を取得し、ファイルシステムとデバイスのI/O層を介してこれらを物理的な読み取り要求に変換します(多くの場合、書き込み要求-たとえばatimeの更新も考えます)。

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

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

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

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

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

この動作は実際に文書化されており、file呼び出しで-sまたは--special-filesを指定することでオーバーライドできますマニュアルページに記載されているように、それは副作用があるかもしれません。以下の引用は、2011年10月17日付のBSDファイル5.11 manページからの引用です。

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

75
a CVn

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

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

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

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

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

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

Enter image description here

例:

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

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

16
stderr

正解です。実際のファイルではありません。

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

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

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

6
LawrenceC

最小限の実行可能な例

私の意見では、これらのことを理解するための最良の方法は、実際に遊んでみることです。そこで、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ファイルを使用すると、openreadllseekなどの任意の「ファイル関連のシステムコール」を実装できることがわかります。

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

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

たとえば、この小さな例では、readが常にabcd\nを返す不要なファイルを作成します。

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

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

/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.
3
Shailesh