1. 概要

このチュートリアルでは、Linux古いファイルハンドルを扱います。 これらは、特に共有されているファイルを処理するときに比較的一般的に発生します。 古いファイルハンドルに取り組むには、まず、ファイルの一般的な考え方を明確にする必要があります。

このチュートリアルのコードには テストされた GNU Bash5.0.3を搭載したDebian10.10(Buster)で。 これはPOSIXに準拠しており、そのような環境で機能するはずです。

2. インデックスノード

インデックスノード(inode)は、他の同様の要素を記述するファイルシステム要素です。基本的に、ファイルやディレクトリなどのオブジェクトも存在するには、iノードが存在する必要があります。 この記事では、iノードが関連付けられているファイルシステムオブジェクトにファイルという用語を使用します。

stat (統計)コマンドを使用して、特定のファイルの詳細を表示します。

user@baeldung:~$ stat filename
File: filename
Size: 583 Blocks: 8 IO Block: 4096 regular file
Device: 810h/2064d Inode: 666 Links: 1
[...]

ファイルfilenameは、iノード番号666(最後の行)を参照しています。

しかし、誰がファイルを参照しますか?

3. ファイルハンドル

ファイルハンドル(ファイル記述子)は単なる整数です。 プロセスはそれらを使用して、開いているファイルのシステムテーブルにインデックスを付けます(ファイルの説明) 。 ファイルハンドルは、ファイルシステム要素とは異なり、ファイルシステム上に存在したり、ファイルシステムで更新されたりすることはありません。 代わりに、開いているファイルの登録を保持するためにプロセスによって使用されます。

proc(プロセス情報)疑似ファイルシステムで -l (ロングリスト形式)フラグを指定して ls (リスト)コマンドを適用することにより、このレジスタをリストします。 :

user@baeldung:~$ ls -l /proc/1296/fd
total 0
lrwx------ 1 user user 64 Jul 1 10:49 0 -> /dev/pts/1
lrwx------ 1 user user 64 Jul 1 10:49 1 -> /dev/pts/1
lrwx------ 1 user user 64 Jul 1 10:49 2 -> /dev/pts/1
lrwx------ 1 user user 64 Jul 1 10:50 3 -> /home/user/filename

出力は、ファイル記述子3がファイル / home / user /filenameを指していることを示しています。 その記述子でstat-L(逆参照リンク)フラグとともに使用すると、ファイルのiノード番号が表示されます。

user@baeldung:~$ stat -L /proc/1296/fd/3
File: /proc/1296/fd/3
Size: 583 Blocks: 8 IO Block: 4096 regular file
Device: 810h/2064d Inode: 666 Links: 1
[...]

ファイルはiノードを参照します。 ファイルハンドルを介して参照ファイルを処理します。 では、ファイルハンドルはどのように古くなるのでしょうか。

4. 古いファイルハンドル

ファイルは、同じiノードを指す多くの名前で存在する可能性があります。 ただし、iノードが参照またはハードリンクされていない場合は、将来の使用のために解放されます。

この時点で、関連するファイルハンドルは、存在しないか一致しない(異なるiノード番号)ファイルを指し続けます。 それらは古いファイルハンドルになりました。 問題のファイルを再作成しても、カーネルが同じiノード番号を再利用することはほぼ不可能です。

結果として生じるエラーはさまざまな方法で発生しますが、標準コードは ESTALE 116 であり、メッセージ Stale file handle:

user@baeldung:~$ cd /mounted
-bash: cd: /mounted: Stale file handle

プロセスがエラーを処理しない場合、プロセスは何も出力しないか、不足しているファイルを要求する可能性があります。

この状況には通常、1つの標準的な修正があります。

5. 古いファイルハンドルを解決する

プロセスがファイルを再度開くと、古いファイルハンドルが更新されます。 そうすることで、ファイルの説明がファイルの新しいiノード番号(存在する場合)で更新されます。 ほとんどの場合、プロセスはこれを内部で実行する必要があります。 そうしないと、再起動する必要がある場合があります。

このソリューションは単純ですが、マウントされた共有ディレクトリでは簡単ではありません。

古いファイルハンドルが更新されない最も一般的なシナリオは、NFSまたはCIFSにマウントされた共有ディレクトリです。 このようなプロトコルの実装には、標準化されたキャッシュとファイルハンドルの同期が欠けていることがよくあります。 このようなシナリオでは、通常、再マウント(場合によっては異なるオプションを使用)またはサーバープロセスの再起動が必要です。 これらのアクションは両方ともダウンタイムを引き起こす可能性があります。

6. 概要

この記事では、古いファイルハンドルについて説明しました。 ファイルが(iノードからファイルへのファイルハンドルへ)ある参照のチェーンと、そのチェーンがどのように壊れることができるか、そしてどのように壊れるかを調べました。

結論として、古いファイルハンドルが発生するさまざまなシナリオでそれらを修正する方法を説明しました。