NFS上のflock(2)とfcntl(2)


19

Perl 5.xのドキュメントでは、flock(..)の実装では、1から始まり、利用できない場合は3に向かって進む、次のネイティブコールのいずれかを使用するように規定されています。

  1. 群れ(2)
  2. fcntl(2)
  3. lockf(3)

それはいいです。ただし、flock(2)をNFS上で使用すべきではないという免責事項に気付いているかもしれません。このドキュメントでは、-Ud_flockフラグを使用してPerlにflock(2)を強制的に使用することを推奨しています。flock(2)(Redhat)のmanページには、NFSの問題に関する同様の免責事項が記載されています。

私の質問は、なぜ!?!?NFSでflock(2)が安全でない理由の詳細な記事や説明を見つけることができないようです。

Redhat(flock(2)が使用されている場所)とSolaris(fcntl(2)が使用されている場所)の両方で、CとPerlでいくつかのテストスクリプトを作成しました。Perlが実際にflock(2)とfcntl(2)をそれぞれ使用していることを確認するために、strace / trussを実行しました。ロックが守られていない問題を再現できませんでした!何が?

回答:


3

Lennart Poetteringは最近、Linuxファイルシステムのロック動作を掘り下げましたが、NFSを介したロックについては特にバラ色の絵は描かれていません(特に、投稿の下部で彼がリンクしているフォローアップ)。

http://0pointer.de/blog/projects/locking.html


1
それは私が探していた正確なタイプの情報です。ありがとうございました!数週間の調査の後、私が訪れたのは非常によく似た解決策ですが、私の疑いを確認する(そして他のことを示唆する)記事を読むのは素晴らしいことです。そのページのコメントからのリンクも参考資料であり、POSIXとその歴史に関する優れた記事です):samba.org/samba/news/articles/low_point/tale_two_stds_os2.html
Jmoney38

15

私はあなたがレガシーの懸念を見ていると確信しています。Perl5マニュアルは1994年にリリースされ、1991年のPerl4のマニュアルの単なる編集であったことを思い出してください。当時、Nightmare File Systemについてよく言われたのは、驚きますが、それはまったく踊ります」。

1991年のNFS2は、Sunから他のプラットフォームにゆっくりと移動し、比較的粗雑でした。セキュリティモデルは本質的に存在せず(クライアントマシンのルートはNFSマウントのすべての内容を読み取ることができます)、ロック(nfs.lockd経由)は実験的なものでした。2つの異なる相互運用可能と思われる実装間で、群れのセマンティクスが適切に動作することを期待するのは愚かだったでしょう。多くのネットワークユーザーが使用することに不快感を感じたことがない(50Ωの終端抵抗器を装着し忘れたことはどういう意味ですか?)

Larry Wallと乗組員は、当時のNFSロックの正確性について悲観的な仮定を立てるあらゆる理由がありました。聞いたこともないようなレガシーシステムとの相互運用性で再導入された古いコードを削除します。

それ以来、NFSは大幅に改善され、lockdはLinux 2.6カーネルの機能に時間内に移行しました。2003年以降のシステムのコレクションでは、NFSファイルロックはおそらく実行されている可能性のある多くのプラットフォームでアプリケーション内で十分にテストされている場合、おそらく信頼できます。

上記のすべてはメモリから引き出されたものであり、調査(たとえばhttp://nfs.sourceforge.net/)によって実証される可能性がありますが、証拠は-彼らが言うように-ロックにあり、あなたがそれをテストしなかった場合、破損していると推定されます。


それは素晴らしい分析です。実際、これまでと同じ結論に達しました。リンクを投稿した後、nfs sourceforgeページをもう一度読んで、探しているものを見つけました!これは馬の口から直接の詳細な分析です!
Jmoney38

2
おっと、エンターキー押します... nfs.sourceforge.netにアクセスして、下部のセクションD10でこの問題について詳しく説明します。
Jmoney38

3

もう1つは、Linux-NFS FAQから直接:nfs.sf.net

flock()/ BSDロックを使用して複数のクライアントで使用されるファイルをロックしようとしていますが、ファイルが破損します。どうして?A. flock()/ BSDロックは、2.6.12より前のLinux NFSクライアントでローカルにのみ機能します。fcntl()/ POSIXロックを使用して、ファイルロックが他のクライアントから見えるようにします。

NFSファイルへのアクセスをシリアル化する方法をいくつか示します。

fcntl()/ POSIXロックAPIを使用します。このタイプのロックは、NLMプロトコルまたはNFSv4を介して複数のクライアント間でバイト範囲ロックを提供します。別のロックファイルを使用し、それへのハードリンクを作成します。creat(2)のマニュアルページのO_EXCLセクションの説明を参照してください。初期の2.6カーネルまで、O_EXCLの作成はLinux NFSクライアントではアトミックではなかったことに注意する価値があります。O_EXCLを使用しないでください。2.6.5より新しいカーネルを実行している場合を除き、複数のNFSクライアント間でアトミックな動作を作成し、予期しません。

Perlがデフォルトでflock()/ BSDロックを使用することは既知の問題です。これにより、flock / BSDロックがPOSIXロックのように機能することを期待するSolarisなどの他のオペレーティングシステムから移植されたプログラムが破損する可能性があります。

Linuxでは、ハードリンクの代わりにファイルロックを使用すると、クライアントのキャッシュをサーバーにチェックポイントするという追加の利点があります。ファイルロックが取得されると、クライアントはそのファイルのページキャッシュをフラッシュし、その後の読み取りでサーバーから新しいデータが取得されるようにします。ファイルのロックが解除されると、そのクライアント上のファイルへの変更は、ロックが解除される前にサーバーにフラッシュバックされるため、そのファイルのロックを待機している他のクライアントが変更を確認できます。

2.6.12のNFSクライアントは、POSIXバイト範囲ロックに関してBSDスタイルのロックをエミュレートすることにより、NFSファイルのflock()/ BSDロックをサポートします。同じエミュレーションメカニズムを使用する、またはfcntl()/ POSIXロックを使用する他のNFSクライアントは、Linux NFSクライアントが表示するのと同じロックを表示します。

ローカルLinuxファイルシステムでは、POSIXロックとBSDロックは互いに見えません。したがって、このエミュレーションにより、Linux NFSサーバーで実行されているアプリケーションは、クライアント上のアプリケーションがBSDスタイルまたはPOSIX-スタイルロック。サーバーアプリケーションがflock()BSDロックを使用する場合、NFSクライアントが使用するロックは表示されません。


カーネル3.13。*を実行している2つのNFSクライアントは、お互いのflock()を参照していますか?
reinierpost

私が正しく理解していれば、答えはノーです。何かを見逃していない限り、flocknfsマウント間でロックしていない、ロックしていない、ロックしない。
ダニエルファレル

少なくともNFS4ではそうです。
rjh

3

これは現在古くなっています。NFS4はプロトコル内のロックサポートし(lockdデーモンまたはRPCコールバックメカニズムは不要)、Perlのflock()メソッドは正常に動作します-これは本番環境で使用しています。

非常に古いバージョンのカーネルflock(syscall)がNFSでノーオペレーションとして実装されていて、バイト範囲ロックなどのその他のものは適切にサポートされていませんでした。これがヒステリーの由来です。


ヒントをありがとう。NFS4でマウントすると問題が解決しました。続いaccess.redhat.com/documentation/en-us/red_hat_enterprise_linux/... fstabの設定権を取得します。
マラピン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.