7. トラブルシュート

この節は、NFS をうまく使えない場合にどうすればよいか、 段階を踏んで解説しようというものです。 通常トラブルはクライアント側からその兆候を現しはじめるので、 診断もそこから始めます。

7.1. マウントしたファイルシステムでファイルが見えない

まず最初に、 そのファイルシステムが実際にマウントされているのか確認してください。 方法は何種類かありますが、 一番確かなのは /proc/mounts を見ることです。 ここにはマウントされているファイルシステムと、 それらの詳細が一覧になっています。 これがうまくいかなければ (例えば /proc ファイルシステムを カーネルに組み込んでいなかったとか)、mount -f と入力してみてください (示される情報は少なくなります)。

ファイルシステムがマウントされているようなら、 もしかしたらその上に別のファイルシステムを マウントしてしまったのかもしれません (この場合は両方のボリュームをアンマウントして、再マウントが必要です)。 あるいはサーバでそのボリュームのエクスポートを、 実際のマウントの前に行ってしまったのかもしれません。 この場合 NFS はマウントポイントだけをエクスポートしてしまいます (この場合はサーバで NFS を再起動します)。

ファイルシステムがマウントされていなければ、 マウントしてみてください。 できなければ 症状 3 へ。

7.2. ファイルリクエストがハングしたり、 アクセス待ちでタイムアウトする

通常これは、クライアントがサーバと通信できない場合に起こります。 症状 3 の b 項を見てください。

7.3. ファイルシステムをマウントできない

ボリュームをマウントできない場合に mount が出すエラーは、ほぼ 2 種類です。 それぞれを順に示しましょう。

  1. failed, reason given by server: Permission denied

    これは、ボリュームへのアクセスを サーバから拒否されたときに出るメッセージです。

    1. /etc/exports ファイルを調べて、 そのボリュームがエクスポートされているか、 クライアントが正しいアクセス権限を持っているかを確認しましょう。 例えば、読み取りのアクセスしかないクライアントが、 そのボリュームを ro オプションではなく rw オプションで マウントしようとしていないでしょうか。

    2. nfsd の起動以降に /etc/exports を変更した場合は、exportfs コマンドでそれを NFS に伝えたでしょうか。 exports を確実に再読み込みさせるには、 exportfs -ra コマンドを入力しましょう。

    3. /proc/fs/nfs/exports ファイルを調べ、 ボリュームとクライアントが正しくリストされているか確認しましょう。 (/var/lib/nfs/xtab を見れば、 アクティブなエクスポートすべてに対する 完全なオプションのリストも得られます。) リストにない場合は、正しく再エクスポートされていません。 リストにあった場合は、 サーバがクライアントをあなたの意図通りに 認識しているかを確認しましょう。 例えばそのクライアントの古いリストが /etc/hosts にあって、 サーバはこっちを見ているのかもしれません。 あるいはクライアントの完全なアドレスを書いていないせいで、 名前解決の結果がドメインの別のマシンになっているかもしれません。 例えばクライアントからサーバに sshtelnet でログインしてみましょう。 ここで who と入力すると、 自分のログインセッションがリストに出るはずで、 あなたのクライアントマシンが サーバからどのような名前で見えているかがわかります。 このマシン名を /etc/exports のエントリに書きましょう。 最後に、サーバからクライアントを ping し、 クライアントからサーバを ping してみましょう。 これでもだめだったり、あるいはパケットロスがあった場合には、 より下層のネットワークの問題でしょう。

    4. あるディレクトリを、その子孫のディレクトリと 同時にエクスポートする (例えば /usr/usr/local) ことはできません。 親ディレクトリを適切な許可属性でエクスポートすれば、 そのサブディレクトリはすべて同じ許可属性でマウントできます。

  2. RPC: Program Not Registered (or another "RPC" error):

    これはクライアントが、 サーバで実行中の NFS を検知できなかったことを意味しています。 いくつかの理由が考えられます。

    1. 最初に、NFS が実際にサーバで動作しているかを確認しましょう。 サーバで rpcinfo -p と入力します。 次のような表示が出るはずです。
         program vers proto   port
          100000    2   tcp    111  portmapper
          100000    2   udp    111  portmapper
          100011    1   udp    749  rquotad
          100011    2   udp    749  rquotad
          100005    1   udp    759  mountd
          100005    1   tcp    761  mountd
          100005    2   udp    764  mountd
          100005    2   tcp    766  mountd
          100005    3   udp    769  mountd
          100005    3   tcp    771  mountd
          100003    2   udp   2049  nfs
          100003    3   udp   2049  nfs
          300019    1   tcp    830  amd
          300019    1   udp    831  amd
          100024    1   udp    944  status
          100024    1   tcp    946  status
          100021    1   udp   1042  nlockmgr
          100021    3   udp   1042  nlockmgr
          100021    4   udp   1042  nlockmgr
          100021    1   tcp   1629  nlockmgr
          100021    3   tcp   1629  nlockmgr
          100021    4   tcp   1629  nlockmgr
        
      これらは、NFS の version 2 と 3、rpc.statd version 1、 ネットワークロックマネージャ (サービス名は rpc.lockd) version 1, 3, 4 が動作中であることを示しています。 また NFS が TCP を使っているか UDP を使っているかに応じて、 別々のサービスリストが表示されています。 TCP を明示的に要求した場合を除き、 通常は (常にではありません) UDP がデフォルトになります。

      少なくとも portmapper, nfs, mountd がなければ、 NFS を再起動しなければなりません。 正しく再起動できないときは、 症状 9 に進んでください。

    2. 次にクライアントから調べましょう。 クライアントで rpcinfo -p server と入力します。 server にはサーバの DNS 名か IP アドレスを入れてください。

      リストが表示された場合は、 実行しようとしているマウントのタイプがサポートされているか 確認してください。 Version 3 NFS を使ってマウントしたい場合は、 Version 3 がリストされているか確認します。 NFS over TCP でマウントしたい場合は、 それが登録されているか確認してください (Linux でないクライアントでは、 TCP がデフォルトになっていることがあります)。 出力の見かたに関するより詳しい情報を見るには man rpcinfo としてください。 利用しようとしているマウントのタイプがリストにないときは、 別のタイプのマウントを試してみてください。

      No Remote Programs Registered というエラーが出たときは、 サーバの /etc/hosts.allow ファイルと /etc/hosts.deny ファイルを調べて、 クライアントのアクセスが本当に許可されているか確認してください。 さらに、エントリが正しいようなら、 /etc/hosts (あるいは DNS サーバ) を確認して、クライアントマシンが正しくリストされているか、 サーバからクライアントに ping が打てるかを確認してください。 システムのエラーログに何か参考になるメッセージが 出ていないかも見てみましょう。 /etc/hosts.allow のエントリが間違っている場合の認証のエラーは、 通常 /var/log/messages に出ますが、 システムログの設定によっては別のファイルかもしれません。 syslog の man ページを見ると、ログ設定の理解の助けになるでしょう。 最後に、古い OS では 2 台のマシン間の経路が対称的でないと、 問題を生じることがあります。 クライアントから tracepath [server] と入力し、 出力に "asymmetric" という単語が出ないことを確認してください。 最近の Linux ディストリビューションなら、 経路が非対称であっても問題は生じないはずです。

      Remote system error - No route to host, というエラーになり、しかし ping は届く場合には、 きつすぎるファイアウォールの犠牲になったのでしょう。 おそらくサーバ、またはサーバとクライアントの間に 設置されているであろう、ファイアウォールを調べて下さい。 情報は ipchains, netfilter, ipfwadm の man ページや、 IPChains-HOWTO (JF による日本語訳) とか Firewall-HOWTO (JF による日本語訳) 等から得られます。

7.4. マウントしたボリュームで、 ファイルにアクセスする権限がありません

2 つの原因が考えられます。

書きこみの権限がない場合は、サーバの /proc/fs/nfs/exports を見て、 エクスポートオプションを確認してください。 そのファイルシステムは読み取り専用になっていないでしょうか。 読み取り専用の場合は、 読み書きモードで再エクスポートしなければなりません (/etc/exports を編集した後は exportfs -ra を忘れないように)。 またクライアントの /proc/mounts も調べ、 ボリュームが読み書きモードでマウントされているか確認しましょう (読み取り専用でマウントしている場合は、 もうちょっと特定しやすいエラーメッセージが出ているでしょうが)。 違っていたら rw オプションを付けて再マウントしましょう。

2 つめの原因は、ユーザ名のマッピングに関係しており、 root の場合と非 root の場合とで少々異なります。

root でないときは、 クライアントとサーバでユーザ名が一致していないかもしれません。 クライアントとサーバの両方で id [user] を実行し、UID 番号が同じかどうか確認してください。 異なっているときは、NIS, NIS+, rsync その他、 ユーザ名の同期に用いているシステムに問題があります。 グループ名が一致しているかも確認しましょう。 また、エクスポートの際に all_squash オプションを指定していないかどうかも確認しましょう。 ユーザ名が一致しているときは、 そのユーザには NFS とは無関係な、 より一般的な権限関連の問題があるものと思われます。

root の時は、エクスポートの際に no_root_squash オプションを付けていないのではないでしょうか。サーバで /proc/fs/nfs/exports または /var/lib/nfs/xtab を調べ、 オプションが指定されているか確認してください。 ただし一般には、NFS サーバに root としての書きこみ権限を与えるのは、 よほどの必要がない限り良い考えではありません (Linux NFS がデフォルトでこれを禁止している理由でもあります)。 詳細は Section 6 を見てください。

root squash を用いている場合は、そのままにしておくのがいいでしょう。 root を取得しても、ファイルに対する権限は nobody のものと同じになります。 ただし root がどの uid にマップされるかを決めているのは サーバであることも忘れないように。 デフォルトでは、サーバは /etc/passwd ファイルの nobody エントリの UIDGID を使いますが、/etc/exports ファイルで anonuid オプションや anongid オプションを使えば、これらを変更できます。 クライアントとサーバで、nobody にマップされる UID が同じになっているかも確認しておきましょう。

7.5. 非常に大きなファイルを転送すると、 NFS がサーバの CPU を取ってしまって、止まったようになってしまいます

これは 2.2 カーネルの fsync() コールの問題で、 すべての sync-to-disk リクエストを同時に行うからです。 従って書きこみ時間がファイルサイズの二乗になってしまいます。 可能なら、2.4 カーネルにすれば問題は解決します。 またエクスポートに no_wdelay オプションを指定すれば、 各プログラムはより高速な o_sync() を使うようになります。

7.6. ログに奇妙なエラーメッセージが出る

  1. 次のようなフォーマットのメッセージ:

     Jan 7 09:15:29 server kernel: fh_verify: mail/guest permission failure, acc=4, error=13
     Jan 7 09:23:51 server kernel: fh_verify: ekonomi/test permission failure, acc=4, error=13
      

    これらは NFS の setattr オペレーションが、 書き込み権限のないファイルに対して試みられたときに起こります。 これらのメッセージは無害です。

  2. 次のようなメッセージがログに頻繁に現われる:

     kernel: nfs: server server.domain.name not responding, still trying
     kernel: nfs: task 10754 can't get a request slot
     kernel: nfs: server server.domain.name OK
     

    この "can't get a request slot" というメッセージは、 クライアント側の RPC コードがタイムアウトをたくさん検出 (おそらくはネットワークの混雑やサーバの過負荷のため) したために、同時要求数の値を小さくし、 サーバの負荷を軽減しようとしていることを示しています。 これらのメッセージの原因は、おそらくは性能が悪いためです。 Section 5 を見てみてください。

  3. マウントした後、クライアントで次のようなメッセージが出る:

    nfs warning: mount version older than kernel
      

    これは書いてあるとおりです。mount のパッケージや am-utils をアップグレードしてください (なんらかの理由でアップグレードできない場合は、 コンパイルしなおして、 新しいカーネルの機能がコンパイル時に認識されるようにするだけでも、 取り合えずは回避できます)。

  4. 起動時/終了時に lockd のログにエラーが出る:

    ブートログに次のようなメッセージが出ているのでしょうか:
    nfslock: rpc.lockd startup failed
     

    これらは無害です。古いバージョンの rpc.lockd は手動で起動する必要がありました。しかし新しいバージョンでは nfsd によって自動的に起動されます。 現在のデフォルトの起動スクリプトの多くは、 まだ lockd を直接起動しようとしますが、 これは不要なのです。 このメッセージを止めさせたければ、起動スクリプトを変更すれば OK です。

  5. 次のようなメッセージがログに現われる:

    kmem_create: forcing size word alignment - nfs_fh
       

    これはファイルハンドルが 32 ビットの倍数ではなく 16 ビットであることから来ています。 このためカーネルの機嫌がちょっと悪くなっているのです。無害です。

7.7. 実際のパーミッションが /etc/exports の指定と異なる

/etc/exports はスペースに 非常に 敏感です。 例えば以下の 2 行は同じではありません:
/export/dir hostname(rw,no_root_squash) 
/export/dir hostname (rw,no_root_squash) 
 
先の方は、hostname/export/dir 対する rw アクセスを与え、 root 権限の禁止 (root_squash) はしていません。 二番目のは、hostnamerw 権限を与えて root_squash を指定、 そして「あらゆるホスト」に rw アクセスを与え、 root_squash はしていません。 わかりました?

7.8. おかしな、不安定な振舞いをする

ls のような簡単なコマンドは動作するが、 大量の情報を転送するような作業を行うとマウントポイントがロックする。

2 つの理由が考えられます。

  1. サーバやクライアントで ipchains を使っており、 フラグメント化されたパケットがチェインを通れないようにしていると、 このようなことが起こります。 リモートホストからのフラグメントを許可すれば、再び機能するはずです。 やり方は Section 6.4 を見てください。

  2. マウントオプションの rsizewsize に、 サーバがサポートしているよりも大きな値を指定しているのかもしれません。 rsizewsize を 1024 に減らして、問題が解決するか見てください。 解決したら、再びゆっくりと、より適切な値に増やしてあげてください。

7.9. nfsd が起動しない

/etc/exports を調べ、 root に対する読み取り許可があるか確認してください。 バイナリを調べ、実行ファイルであるか確認してください。 カーネルに NFS サーバのサポートが組み込まれているでしょうか。 これらのいずれでも解決しなければ、 バイナリをインストールしなおす必要があるかもしれません。

7.10. 複数のクライアントを使うとファイルが壊れる

ファイルが修正されてから 1 秒以内に別の修正がなされ、 その際にサイズが変わらなかった場合、 同じ inode 番号が生成されます。 このため、一つのファイルに複数のクライアントから 連続的に読み書きが行われると、ファイルが壊れることがあります。 このバグを修正するには、 ファイルシステムの深い部分を変更しなければならないため、 2.5 における課題になっています。