NFS v4 サーバーは、バインド マウントがサブディレクトリの場合のみ、古いファイル ハンドルを引き起こします。

NFS v4 サーバーは、バインド マウントがサブディレクトリの場合のみ、古いファイル ハンドルを引き起こします。

現時点では、この問題は私を狂わせています。私は次の構成で正常に動作していた Ubuntu 16.04 NFS サーバーを持っています:

/etc/fstab:
UUID=b6bd34a3-f5af-4463-a515-be0b0b583f98  /data2  xfs  rw,relatime  0  0
/data2  /srv/nfs/cryodata    none    defaults,bind    0  0
/usr/local       /srv/nfs/local    none    defaults,bind    0  0

そして

/etc/exports
/srv/nfs  192.168.159.31(rw,sync,fsid=0,crossmnt,no_subtree_check)
/srv/nfs/cryodata  192.168.159.31(rw,sync,no_subtree_check)
/srv/nfs/local      192.168.159.31(rw,sync,no_subtree_check)

これまでのところ、クライアント側の /etc/fstab エントリを使用して、この構成を使用する 1 つの NFS クライアントで数か月間すべて正常に動作しています。

kraken.bio.univ.edu:/local  /usr/local  nfs4  _netdev,auto  0  0
kraken.bio.univ.edu:/cryodata  /cryodata  nfs4  _netdev,auto  0  0

しかし、これは非常に大きなストレージ サーバーであるため、複数のラボを収容する必要があると判断されました。そこで、/data2 パーティションに分散していたすべてのものを /data2/cryodata サブディレクトリに移動し、サーバーの /etc/fstab と /etc/exports を次のように更新しました。

/etc/fstab:
...
/data2/cryodata  /srv/nfs/cryodata    none    defaults,bind    0  0
/data2/xray      /srv/nfs/xray    none    defaults,bind    0  0
/data2/EM        /srv/nfs/EM    none    defaults,bind    0  0
/usr/local       /srv/nfs/local    none    defaults,bind    0  0

そして

/etc/exports
/srv/nfs  192.168.159.31(rw,sync,fsid=0,crossmnt,no_subtree_check)
/srv/nfs/cryodata  192.168.159.31(rw,sync,no_subtree_check)
/srv/nfs/EM  192.168.159.31(rw,sync,no_subtree_check)
/srv/nfs/xray  192.168.159.31(rw,sync,no_subtree_check)
/srv/nfs/local  192.168.159.31(rw,sync,no_subtree_check)

これは単純に機能しません。同じクライアントの /etc/fstab エントリを使用してクライアントに新しいマウントをマウントしようとすると、次のようになります。

{nfs client} /etc/fstab:
...
kraken.bio.univ.edu:/local  /usr/local  nfs4  _netdev,auto  0  0
kraken.bio.univ.edu:/cryodata  /cryodata  nfs4  _netdev,auto  0  0

# mount -v /cryodata
mount.nfs4: timeout set for Sat Feb 24 09:24:38 2018
mount.nfs4: trying text-based options 'addr=192.168.41.171,clientaddr=192.168.159.31'
mount.nfs4: mount(2): Stale file handle
mount.nfs4: trying text-based options 'addr=192.168.41.171,clientaddr=192.168.159.31'
mount.nfs4: mount(2): Stale file handle
mount.nfs4: trying text-based options 'addr=128.83.41.171,clientaddr=129.116.159.31'
...

/usr/local は問題なくマウントされ続けます。最初にこれを試したとき、exportfs -var変更を加える前に使用しているファイルシステムをエクスポート/アンエクスポートするのを忘れましたが、それ以来、何度もサーバーを再起動しながら、すべてをアンエクスポートしてアンマウントするように注意しながら、何度も切り替えてきました。パーティション全体のバインド マウントの最初のマウントは常に機能しますが、サブディレクトリのバインド マウントは、毎回、古い NFS ハンドル メッセージで失敗します。これらのパーティションをマウントしたことのない他の NFS クライアントを有効にしてみましたが、まったく同じエラー メッセージが表示されます。この場合、間違いなくサーバー側の問題です。マウント試行間などに /var/lib/nfs/etab がクリアされていることを確認しました。

NFS サーバーのルート ディレクトリにバインド マウントする手法で、こうした問題はすべて解決できると思っていましたが、どうやらそうではないようです。奇妙なことに、/usr/local は別のパーティションのサブディレクトリであり、常に正常にマウントされます。これは ext3 md raid 1 上にあります。ただし、これが問題になるとは思えません。

私はこれに何時間も費やし、解決策を探すのに Google をほとんど壊しかけましたが、無駄でした。

答え1

バインドマウントされたファイルシステムのみをエクスポートしていることに注意してください。このセクションは輸出関連するマニュアルページ:

fsid=数値|ルート|UUID

NFS は、エクスポートする各ファイルシステムを識別できる必要があります。通常、ファイルシステムの UUID (ファイルシステムに UUID がある場合) またはファイルシステムを保持するデバイスのデバイス番号 (ファイルシステムがデバイスに保存されている場合) が使用されます。

私の誤った仮定は、バインドマウントされたファイルシステムには、NFS が自動的に使用できる何らかの UUID があるというものでした。そして、これらのバインドマウントされたエクスポートは両方とも fsid なしで正常に動作したという事実によって、この仮定は強化されました。

/srv/nfs  192.168.159.31(rw,sync,fsid=0,crossmnt,no_subtree_check)
/srv/nfs/cryodata  192.168.159.31(rw,sync,no_subtree_check)
/srv/nfs/local  192.168.159.31(rw,sync,no_subtree_check)

しかし、これにより動作に一貫性がなくなります。バインドマウントされた /opt を追加しました:

/etc/fstab:
/data1/opt      /srv/nfs/opt  none  defaults,bind    0  0

/etc/exports:
/srv/nfs/opt  192.168.159.3(rw,sync,no_subtree_check)

その結果、一貫性のない動作が発生しました。つまり、エクスポート IP を変更して 1 台のマシンにマウントできるのに、別のマシンではアクセスが拒否されるという状況です。解決策は、fsid を追加することでした。

/etc/exports:
/srv/nfs/opt  192.168.159.3(rw,sync,fsid=20,no_subtree_check)

したがって、解決策は、バインドマウントされたファイルシステムをエクスポートするために常に fsid を追加することです。

関連情報