だから簡単に言えば、私は多くのファイルを開いてその中にデータを書き、ファイルハンドルを正しく閉じずにファイルを削除する(Python)プログラムを書いています。しばらくすると、ディスク容量が不足してプログラムが停止します。
これ以上存在しないファイルが多く、cannot create temp file for here-document: No space left on device"
bashのオートコンプリートが失敗します。lsof -nP +L1
私のプログラムを終了した後、すべてのファイルハンドルが閉じ、ディスクスペースが再び「使用可能」になり、すべてが正常です。
なぜこれが起こるのですか?ディスク領域は物理的に埋められません。それともファイルハンドルの数が制限されていますか?
答え1
Unixからファイルを削除すると、そのデータへの名前付き参照のみが削除されます(したがって、システムコール名unlink
/unlinkat
代わりにdelete
)。データ自体を公開するには、そのデータへの他の参照があってはなりません。参考文献は、次の方法で入手できます。
- このデータは、もはやファイルシステムで参照されるべきではありません(
st_nlink
ゼロでなければなりません)。これはハードリンクで発生する可能性があります。それ以外の場合は、ファイルシステムがアクセスし続けながらデータを削除します。 - このデータは開いたファイルハンドルで参照できなくなります(Linuxでは、カーネルの相関はゼロでなければなりません)
struct file
。f_count
それ以外の場合は、ファイルハンドル(またはLinux上)を読み書きする方法でデータに/proc/pid/fd
アクセスまたは変更を加えることができるので、どこかに保存する必要があります。
これら2つの条件が満たされると、データが公開される可能性があります。状況が条件#2に違反しているため、ファイルハンドルはまだ開いています。ファイルハンドルが閉じられるまで、データは別の場所に行く場所がないため、ディスクに保存され続けます。
一部のプログラムでは、これを使用してデータのクリーンアップを簡素化することもできます。たとえば、途中で作業するために大量のデータをディスクに保存する必要があるが、他の人と共有する必要がないプログラムを想像してみてください。ファイルを開いてすぐに削除すると、終了時にクリーンアップされたことを心配することなくファイルを使用できます。開かれたファイル記述子参照数はclose(fd)
終了時に自然にゼロになり、次の場合に関連スペースが解放されます。プログラムは正常に終了します。
発覚
ファイル記述子によってまだ開いている削除されたファイルは、以下をlsof
使用して見つけることができます。
% lsof -nP +L1
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NLINK NODE NAME
pulseaudi 1799 cdown 6u REG 0,1 67108864 0 1025 /memfd:pulseaudio (deleted)
chrome 46460 cdown 45r REG 0,27 131072 0 105357 /dev/shm/.com.google.Chrome.gL8tTh (deleted)
st_nlink
値が1未満の開いているすべてのファイルが一覧表示されます。
少ない
あなたの場合は、プロセスを終了してファイルハンドルを閉じることができます。これは可能であれば良い解決策です。
これが不可能な場合、Linuxはファイル記述子がサポートするデータにアクセスし、ファイルが削除されて/proc/pid/fd
もサイズ0に切り捨てることができます。
: > "/proc/pid/fd/$num"
アプリケーションが後で対応するファイル記述子を使用して実行する操作に応じて、アプリケーションは以下のようにデータが変更されることについてさまざまな怒りを感じることがあります。
ファイルディスクリプタが漏れて再びアクセスできないと確信している場合は、を使用して閉じることもできgdb
ます。まず、またはlsof -nP +L1
を使用してls -l /prod/pid/fd
関連するファイル記述子番号を見つけて、次の手順を実行します。
% gdb -p pid --batch -ex 'call close(num)'
あなたの質問の理由ではありませんが、他の質問に答えるには、次の手順を実行します。
ファイル[説明者]の数が制限されていますか?
ファイル記述子の数はい制限されていますが、ここで直面する制限ではありません。 「デバイスに残りのスペースがない」とは、ENOSPC
ファイルシステムのスペースが不足した場合に作成されることです。ファイル記述子の制限に達するとEMFILE
(「開いているファイルがstrerror
多すぎる」と表示されるプロセスレベルが不足している)、または(「システムに開いているファイルが多すぎる」と表示されるENFILE
システムレベルが不足している)メッセージが表示されます。strerror
プロセスレベルのソフト制限はで確認でき、ulimit -Sn
システムレベルの制限はで確認できます/proc/sys/fs/file-max
。
答え2
(現在削除されている)ファイルへのハンドルを保持している限り、(ハンドルを保持しているプロセスで)そのデータに引き続きアクセスできます。このデータには保存する場所が必要です。