ファイルが完了した後にのみnfsv3でファイルを処理する方法は?

ファイルが完了した後にのみnfsv3でファイルを処理する方法は?

別のシステムでファイル(特定のサイズ)を書き込むNFSマウントがあり、新しいファイルをポーリングしています。スクリプトを使用してファイルを処理するには、ファイルが完全に完了するまで待つ必要があります。私はこれらのファイルや名前を書くプロセスを制御しません。

fusionrとlsofが私のローカルシステムを調べているようですが、他のシステムがNFSマウントに書き込んだ場合、それは正しく処理されません。 v3の場合、ファイルイベントを聞くことができるとは思わず(しかしv4も聞くことができますか?)、ファイルサイズが大きくならなくなるまでしばらく待つ必要はありません(そしてネットワークが拡張されないことを祈ります)。間違っています)、そうする方法があるかどうかわかりません。ローカルでファイルハンドルを見つけるのと同じように、整合性が保証されます。解決策はありますか?そうでなければ、NFSv4のソリューションはありますか?

答え1

nfsv3はステートレスであるため、そのステータスを保証する方法はありません。ただし、NLM(Network Lockout Manager)が両側で実行されている必要があります。

nfsv4にはロック操作のオープン/読み取り/書き込み/ロック/クローズがあり、OPEN CLOSE状態を維持します。可能であれば、nfsv4に変更する必要があります。

http://nfs.sourceforge.net/#faq_a6

答え2

理想的な解決策は、送信者が.tmp一時サフィックス()を使用してファイルをNFS共有に配置し、コピーが完了した後にのみ名前を変更することです。

# Sender
# There are better ways of writing this code; it's just an illustration
#
if cp /from/source/data.xml /to/nfs/share/data.xml.tmp
then
    # copy succeeded; rename
    mv -f /to/nfs/share/data.xml.tmp /to/nfs/share/data.xml
fi

NFSでも名前の変更は原子的に行われるため、受信者がサフィックス付きファイルを無視する限り、他のすべての.tmpファイル(data.xmlこの例では)はすぐにNFS共有に完全に受信者に表示されます。

しかし、残念ながら、あなたは送信者を制御できないと説明します。

この場合、ファイルが完全に転送されたことを保証するために実際に実行できることはあまりありません。さまざまなオプションには、データ内のENDタグ(送信されるデータに固有のタグ、リテラル「END」文字列である必要はありません)を見つける、またはファイルを処理する前にファイルを解析する試みが含まれます。以下は、XMLファイルを確認する例です。

# XML validation
if xmlstarlet validate /to/nfs/share/data.xml
then
    # An XML file validated so it must be complete
    ...
fi

数分間変更されていないファイルだけを考慮するメソッドにこれを追加すると、うまくいく解決策が得られます。

find /to/nfs/share -type f -mmin +5 -name '*.xml' -print0 |
    while IFS= read -d '' file
    do
        if validate-the-file "$file"
        then
            process-the-file "$file"
            rm -f "$file"
        fi
    done

または

find /to/nfs/share -type f -mmin +5 -name '*.xml' -exec sh -c '
    for file in "$@"
    do
        process-the-file "$file"
        rm -f "$file"
    done
' _ {} +

関連情報