常に一貫性を保つ必要のあるデータを含むファイルがあります。変更が必要な場合は、Process 1
新しいファイルを作成し、変更内容を新しいファイルに書き込み、を使用してmv
新しいファイルの名前を古いファイル名に変更します。
このファイルを読み取る必要がある別のプロセス がある場合Process 2
、常に一貫性のあるファイルを読み取ること、つまり読み取り中にmv
によってProcess 1
データが破損しないことをどのように保証できますか?
答え1
これは、古いファイルと同じファイルシステム上に新しいファイルを作成し、rename(2)
アトミックであることが保証されている [1] 関数を使用することで保証されます。
Unix ファイルシステムでは、はrename(2)
ディレクトリ エントリに対してのみ作用し、元の dir エントリによって指される inode へのオープン ハンドルを持つプロセスには影響しません。そのプロセスは、古いファイルからの読み取りまたは古いファイルへの書き込みを続行します。
通常、mv(1)
ユーティリティは を呼び出すだけですrename(2)
が、 が失敗した場合には、削除 + コピーまたはその他の疑わしい非アトミック操作にフォールバックすることがありますrename(2)
。
2 つのファイルが同じファイルシステム上にある場合、操作が成功するとは限らないことに注意してくださいrename(2)
。 のようなファイルシステムでは9pfs
名前変更操作がサポートされていないため、何らかの方法で操作を行う必要があります。
[1] あるいはさらに良い方法として、renameat(2)
ファイルへの主要なパスが別のプロセスによって密かに変更されること、つまり「シンボリックリンク攻撃」を防止します。