Linuxで開いているファイルの数が制限されているのはなぜですか?


136

今、私は方法を知っています:

  • プロセスごとに開くファイルの制限を見つける: ulimit -n
  • すべてのプロセスで開かれているすべてのファイルをカウントします。 lsof | wc -l
  • 開いているファイルの最大許容数を取得します。 cat /proc/sys/fs/file-max

私の質問は次のとおりです。Linuxで開いているファイルに制限があるのはなぜですか?


2
@Robは少しグーグルで検索し、それがフォークボムであることを発見し、オープンファイル制限を説明するために使用できますか?
xanpeng

6
さて、プロセス制限とファイル制限は重要です。フォーク爆弾のようなものは、すべてのユーザーのサーバー/コンピューターを破壊せず、それを行うユーザーのみを一時的に破壊します。そうしないと、共有サーバー上の誰かがフォークボムを作動させ、自分だけでなくすべてのユーザーに完全に破壊する可能性があります。
ロブ

3
とても便利なコマンドをまとめた素敵なものです!:+1:
ジョシュアピンター

7
@Rob、フォーク爆弾は、ファイル制限がプロセスごとにあり、フォークするたびに新しいファイルハンドルを開かないため、これとは関係ありません。
psusi

回答:


86

その理由は、オペレーティングシステムが開いている各ファイルを管理するためにメモリを必要とし、メモリが限られたリソースであるためです-特に組み込みシステムでは。

rootユーザーとして、プロセスごと(を介してulimit -n)およびシステムごと(例えばecho 800000 > /proc/sys/fs/file-max)に開くことができるファイルの最大数を変更できます。


21
セキュリティ上の理由もあります。制限がなければ、ユーザーランドソフトウェアはサーバーがダウンするまで無限にファイルを作成できます。
コーレン

15
@Corenここで説明する制限は、開いているファイルハンドラーの数のみです。プログラムはファイルハンドラーを閉じることもできるため、使用可能なすべてのディスク領域がいっぱいになるまで、必要なだけ多くのファイルを作成できます。これを防ぐには、ディスククォータまたは個別のパーティションを使用できます。セキュリティの1つの側面はリソースの枯渇を防ぐことであるという意味で、あなたは真実です。このためには制限があります。
ジョフェル

1
@jofelありがとう。開かれたファイルハンドルはstruct fileのインスタンスによって表され、この構造体のサイズは非常に小さい(バイトレベル)ので/.../file-max、メモリが消費されない限り非常に大きな値を設定できますか?
ザンペン

7
@xanpeng私はカーネルの専門家ではありませんが、私の知る限りでは、デフォルトはfile-maxRAMサイズを10kで割った値のようです。ファイルハンドラごとに使用される実際のメモリははるかに小さくする必要があるため(サイズにstruct file加えていくつかのドライバ依存メモリ)、これはかなり控えめな制限のようです。
ジョフェル

63

lsof | wc -l重複エントリの多くを合計することに注意してください(分岐したプロセスはファイルハンドルなどを共有できます)。その数は、で設定された制限よりもはるかに高い可能性があります/proc/sys/fs/file-max

Linuxカーネルの観点から現在開いているファイルの数を取得するには、次の操作を行います。

cat /proc/sys/fs/file-nr

例:このサーバーには、最大65536個のオープンファイルのうち40096個がありますが、lsofの報告数ははるかに多くなっています。

# cat /proc/sys/fs/file-max
65536
# cat /proc/sys/fs/file-nr 
40096   0       65536
# lsof | wc -l
521504

1
lsof2倍以上、など多くのファイルを報告します/dev/null、あなたが最良の推測を試すことができます:lsof|awk '{print $9}'|sort|uniq|wc -l
イヴァン

lsof|awk '!a[$NF]++{c++}END{print c}'開いているファイルの重複しないカウントを取得するために使用できます。
P ....

18

主に歴史的な理由によるものだと思います。

Unixのファイルディスクリプタは小さいintように関数が返す値、openおよびcreat、と渡されたreadwriteclose、など。

少なくともUnixの初期のバージョンでは、ファイル記述子は単に、構造のプロセスごとの固定サイズの配列へのインデックスであり、各構造には開いているファイルに関する情報が含まれていました。正しく思い出せば、初期のシステムの中にはこのテーブルのサイズを20程度に制限していたものがありました。

最新のシステムにはより高い制限がありますが、同じ一般的なスキームを維持しており、大部分は慣性から外れています。


1
20は、C言語のFILEデータ構造に対するSolarisの制限でした。ファイルハンドル数は常に大きくなりました。
ローサー

@Lothar:興味深い。なぜ制限が異なるのだろうか。関数filenofdopen関数を考えると、それらはほぼ互換性があると思われます。
キーストンプソン

UNIXファイルは、返されるファイルハンドル(int)以上のものです。ディスクバッファーと、現在のファイルオフセット、ファイル所有者、アクセス許可、iノードなどを定義するファイル制御ブロックがあります。
ChuckCottrill

@ChuckCottrill:はい、もちろん。しかし、その情報の大部分は、ファイルがint記述子またはFILE*。で20を超えるファイルを開いているopen()場合、fdopen()失敗しますか?
キーストンプソン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.