このセクションでは、NFS Version 4 で導入された機能について説明します。
NFS サービスの設定については、NFS サービスの設定を参照してください。
NFS Version 3 と Version 4 の両方で、クライアントが共有解除されたファイルシステムにアクセスしようとすると、サーバーはエラーコードを返します。ただし、NFS Version 3 では、サーバーはファイルシステムが共有解除される前にクライアントが取得したロックを保持します。したがって、ファイルシステムが再共有されると、NFS Version 3 クライアントは、そのファイルシステムが共有解除されなかったかのようにファイルシステムにアクセスできます。
NFS Version 4 では、ファイルシステムが共有解除されると、そのファイルシステム内のオープンファイルまたはファイルロックに関するすべての状態情報が破棄されます。クライアントは、これらのファイルにアクセスしようとしたりロックしようとしたりすると、エラーを受け取ります。このエラーは通常、アプリケーションに対する入出力エラーとして報告されます。ただし、オプションを変更するために現在共有されているファイルシステムを再共有しても、サーバーの状態情報は破棄されません。
NFS Version 4 のクライアント回復については、NFS version 4 におけるクライアント回復を参照してください。unshare コマンドで使用可能なコマンドオプションについては、unshare_nfs(1M) のマニュアルページを参照してください。
NFS Version 4 サーバーは、サーバー上のすべてのエクスポート済みファイルへのシームレスアクセスをクライアントに提供する、擬似ファイルシステムを作成および保守します。NFS Version 4 以前は、擬似ファイルシステムは存在しませんでした。クライアントは、アクセスする各共有サーバーのファイルシステムに強制的にマウントされます。
擬似ファイルシステムは、ディレクトリだけを含む構造で、サーバーによって作成されます。擬似ファイルシステムを介して、クライアントはエクスポート済みファイルシステムの階層を参照します。つまり、クライアントから見る擬似ファイルシステムは、エクスポート済みファイルシステムに関連付けられたパスに制限されます。
以前のバージョンの NFS では、クライアントは、サーバーのファイルシステムを検索するには、各ファイルシステムをマウントする必要がありました。ただし、NFS Version 4 ではサーバー名前空間が次のことを行います。
クライアントから見えるファイルシステムをサーバーエクスポートに関連付けられたディレクトリに制限します。
サーバーエクスポートへのシームレスアクセスをクライアントに提供します (クライアントは配下の各ファイルシステムをマウントする必要がない)。ただし、オペレーティングシステムが異なるときは、クライアントが各サーバーファイルシステムをマウントしなければいけない場合があります。
図 2-2 NFS Version 4 でのサーバーファイルシステムおよびクライアントファイルシステムの見え方
図に示されている例では、クライアントは payroll ディレクトリと nfs4x ディレクトリを見ることができません (これらのディレクトリはエクスポート済みではなく、エクスポート済みディレクトリに関連付けられていないため)。ただし、local ディレクトリはエクスポート済みディレクトリであるため、local ディレクトリはクライアントが見ることができます。projects ディレクトリはエクスポート済みディレクトリ nfs4 に関連付けられているため、projects ディレクトリはクライアントが見ることができます。つまり、サーバー名前空間のうち明示的にエクスポート済みでない部分は、擬似ファイルシステムでブリッジされ、これ経由でエクスポート済みディレクトリおよびサーバーエクスポートに関連付けられたディレクトリだけを見ることになります。
ファイルハンドルは、サーバー上で作成され、ファイルとディレクトリを一意に識別する情報を持ちます。NFS Version 2 と Version 3 では、サーバーが永続ファイルハンドルを返しました。したがって、クライアントは、サーバーが常に同じファイルを参照するファイルハンドルを生成することを保証できました。次に例を示します。
ファイルが削除され同じ名前のファイルに置き換えられた場合、サーバーは必ず新しいファイルの新しいファイルハンドルを生成する。クライアントが古いファイルハンドルを使用していた場合、サーバーはファイルハンドルが無効であることを示すエラーを返す。
ファイル名が変更されている場合、ファイルハンドルは変更されない。
サーバーがリブートされた場合、ファイルハンドルは変更されない。
このように、サーバーがファイルハンドルを含むクライアントからの要求を受け取った場合、解決策は単純であり、ファイルハンドルは常に正しいファイルを参照します。
NFS 操作のために永続ファイルハンドルを使用してファイルとディレクトリを識別する方法は、ほとんどの UNIX ベースサーバーで機能しました。ただし、この方法は、ファイルのパス名などほかの識別方法を使用するサーバー上では実装できません。この問題を解決するために、サーバーは NFS Version 4 プロトコル経由でそのファイルハンドルが揮発性であることを宣言できます。ファイルハンドルが変更された場合、クライアントは新しいファイルハンドルを検出する必要があります。
NFS Versions 2 と NFS Version 3 サーバーと同様に、Oracle Solaris NFS Version 4 サーバーは常に永続ファイルハンドルを提供します。ただし、Oracle Solaris NFS Version 4 以外のサーバーにアクセスする Oracle Solaris NFS Version 4 クライアントは、サーバーが揮発性ファイルハンドルを使用する場合はそれらをサポートする必要があります。具体的には、サーバーがクライアントにファイルハンドルが揮発性であることを通知すると、クライアントはパス名とファイルハンドル間のマッピングをキャッシュする必要があります。クライアントは、期限切れになるまで、揮発性ファイルハンドルを使用します。期限が切れたとき、クライアントは次を実行します。
そのファイルハンドルを参照するキャッシュされた情報をフラッシュする
そのファイルの新しいファイルハンドルを検索する
操作を再試行する
揮発性ファイルハンドルはこれらの状況で期限切れになる可能性があります。
ファイルを閉じたとき
ファイルハンドルのファイルシステムが移行するとき
クライアントがファイル名を変更するとき
サーバーがリブートするとき
クライアントが新しいファイルハンドルを見つけられない場合、エラーメッセージログが syslog ファイルに記録されます。このファイルにさらにアクセスしようとすると、入出力エラーで失敗します。
NFS Version 4 プロトコルはステートフルプロトコルです。クライアントとサーバーの両方が、オープンファイルとファイルロックに関する現在の情報を保守します。
サーバーがクラッシュしてリブートしたとき、サーバーの状態は消失します。クライアントは、サーバーがリブートしたことを検出すると、障害の前に存在していたオープンおよびロック状態をサーバーが再確立するのを支援するプロセスを開始します。このプロセスは、クライアントがプロセスを指示するため、クライアント回復と呼ばれています。
クライアントは、サーバーがリブートしたことを検出すると、ただちに現在の動作を停止して、クライアント回復のプロセスを開始します。回復プロセスが開始されると、次のようなメッセージが、システムエラーログ /var/adm/messages に表示されます。
NOTICE: Starting recovery server server-name
回復プロセスの間、クライアントは、クライアントの以前の状態に関するサーバー情報を送信します。ただし、この間、クライアントはサーバーに新しい要求を送信しません。ファイルを開いたりファイルロックを設定したりするための新しい要求は、サーバーが回復プロセスを完了するのを待ってから続行する必要があります。
クライアント回復プロセスが完了すると、次のメッセージがシステムエラーログ /var/adm/messages に表示されます。
NOTICE: Recovery done for server server-name
この時点で、クライアントはサーバーに状態情報を送信するのを正常に完了しました。ただし、クライアントがこのプロセスを完了しても、ほかのクライアントがそうでない可能性があります。つまり、猶予期間と呼ばれる期間は、サーバーはすべてのクライアントがそれぞれの回復を完了できるように、いかなるオープンおよびロック要求も受け入れません。
猶予期間中に、クライアントが新しいファイルを開こうとしたり、新しいロックを確立しようとしたりすると、サーバーは GRACE エラーコードで要求を拒否します。このエラーを受け取ったクライアントは、猶予期間が終わるのを待ってから、要求をサーバーに再送信します。猶予期間中は、次のメッセージが表示されます。
NFS server recovering
猶予期間中も、ファイルを開いたりファイルロックを設定したりしないコマンドは処理できます。たとえば、コマンド ls と cd はファイルを開いたりファイルロックを設定したりせず、これらのコマンドは一時停止しません。ただし、ファイルを開く cat などのコマンドは、猶予期間が終わるまで中断されます。
猶予期間が終了すると、次のメッセージが表示されます。
NFS server recovery ok.
クライアントは、サーバーに新しいオープン要求またはロック要求を送信できるようになります。
クライアント回復は、さまざまな理由により失敗することがあります。たとえば、サーバーのリブート後にネットワークパーティションが存在する場合、クライアントは、猶予期間が終了する前にサーバーとの状態を再確立できない場合があります。猶予期間が終了すると、新しい状態操作により競合が発生する可能性があるため、サーバーはクライアントに状態の再確立を許可しません。たとえば、新しいファイルロックは、クライアントが回復しようとしている古いファイルロックと競合します。このような状況が発生すると、サーバーは NO_GRACE エラーコードをクライアントに返します。
ファイルに対するオープン操作の回復が失敗すると、クライアントはファイルを使用不可能としてマークし、次のメッセージが表示されます。
WARNING: The following NFS file could not be recovered and was marked dead (can't reopen: NFS status n): file : filename
回復に失敗している間にファイルロックを再確立すると、次のエラーメッセージが表示されます。
NOTICE: nfs4_send_siglost: pid process-ID lost lock on server server-name
この場合、SIGLOST シグナルがプロセスに送信されます。SIGLOST シグナルのデフォルトの動作は、プロセスを中断することです。
この状態から回復するには、障害発生時にファイルを開いていたアプリケーションを再起動する必要があります。ファイルを再度開くことができない一部のプロセスは入出力エラーを受け取る可能性があります。ファイルを再度開いたり、回復の失敗後にオープン操作を実行したりしたほかのプロセスは、問題なくファイルにアクセスできます。
このように、特定のファイルにアクセスできるプロセスとアクセスできないプロセスがあります。
NFS Version 4 プロトコルにはファイル共有モードがいくつか用意されていて、クライアントはほかのクライアントによるファイルアクセスを制御するために使用できます。クライアントは、次のように指定できます。
DENY_NONE モードを指定すると、ほかのクライアントはファイルへの読み取りと書き込みアクセスを許可されます。
DENY_READ モードを指定すると、ほかのクライアントはファイルへの読み取りアクセスを拒否されます。
DENY_WRITE モードを指定すると、ほかのクライアントはファイルへの書き込みアクセスを拒否されます。
DENY_BOTH モードを指定すると、ほかのクライアントはファイルへの読み取りと書き込みアクセスを拒否されます。
Oracle Solaris NFS Version 4 サーバーは、これらのファイル共有モードを完全に実装します。したがって、クライアントが現在の共有モードと矛盾する方法でファイルを開こうとすると、サーバーは操作を失敗させて、その試行を拒否します。このような試行がファイルのオープンまたは作成操作の開始で失敗すると、NFS Version 4 クライアントはプロトコルエラーを受け取ります。このエラーは、アプリケーションエラー EACCES にマップされます。
プロトコルはいくつかの共有モードを提供していますが、Oracle Solaris でのオープン操作は複数の共有モードを提供していません。ファイルを開くとき、Oracle Solaris NFS Version 4 クライアントは、DENY_NONE モードだけを使用できます。
NFS Version 4 は、委託のためにクライアントサポートとサーバーサポートを提供します。委託は、サーバーがファイルの管理をクライアントに委託するためのテクニックです。たとえば、サーバーは、読み取り委託または書き込み委託のいずれかをクライアントに付与できます。読み取り委託は互いに競合しないため、複数のクライアントに同時に付与できます。書き込み委託はほかのクライアントによるファイルアクセスと競合するため、1 つのクライアントにだけ付与できます。書き込み委託を保持している間、クライアントは、ファイルへの排他的アクセスを保証されているために、さまざまな操作をサーバーに送信しません。同様に、読み取り委託を保持している間、クライアントはさまざまな操作をサーバーに送信しません。クライアントが書き込みモードでファイルを開けないことをサーバーが保証するためです。
委託により、委託されたファイルに対するサーバーとクライアントの相互作用を大幅に減少することができます。したがって、ネットワークトラフィックが減少し、クライアントとサーバーのパフォーマンスが向上します。ただし、パフォーマンス向上の度合いは、アプリケーションが使用するファイル相互作用の種類およびネットワークとサーバー輻輳の量によって異なります。
クライアントは、委託を要求しません。委託を付与するかどうかの決定は、ファイルのアクセスパターンに基づいてサーバーがすべて行います。ファイルが最近複数の異なるクライアントから書き込みモードでアクセスされた場合、このアクセスパターンが将来競合する可能性を示しているためサーバーは委託を付与しないことがあります。
競合は、ファイルに付与されている委託と一致しない方法でクライアントがそのファイルにアクセスするときに発生します。たとえば、あるクライアントがファイルの書き込み委託を保持しており、2 番目のクライアントが読み取りまたは書き込みアクセス用にそのファイルを開くとサーバーは最初のクライアントの書き込み委託を再呼び出しします。同様に、あるクライアントが読み取り委託を保持しており、別のクライアントが書き込み用に同じファイルを開くと、サーバーは読み取り委託を再呼び出しします。どちらの場合も、競合が現在存在しているため、2 番目のクライアントは委託を付与されません。
競合が発生すると、サーバーはコールバックメカニズムを使用して、委託を保持しているクライアントと連絡をとります。このコールバックを受信すると、クライアントはファイルの更新された状態をサーバーに送信し、委託を返します。クライアントが再呼び出しに対する応答に失敗すると、サーバーは委託を取り消します。こうした場合、サーバーはこのファイルに対するクライアントの操作をすべて拒否し、クライアントは要求された操作を失敗として報告します。一般的に、これらの失敗は入出力エラーとしてアプリケーションに報告されます。これらのエラーから回復するには、ファイルを閉じてから再度開く必要があります。取り消された委託による失敗は、クライアントが委託を保持している間にクライアントとサーバー間にネットワークパーティションが存在しているときに発生します。
サーバーは、別のサーバーに格納されているファイルに対するアクセス競合を解決できません。つまり、NFS サーバーは、格納しているファイルに対する競合だけを解決します。さらに、さまざまなバージョンの NFS を実行しているクライアントによって発生する競合に対して、NFS サーバーは NFS Version 4 を実行しているクライアントにだけ再呼び出しを開始できます。以前のバージョンの NFS を実行しているクライアントに再呼び出しを開始できません。
競合を検出するプロセスはさまざまです。たとえば、NFS Version 4 とは異なり、NFS Version 2 と NFS Version 3 にはオープン手順がないため、クライアントがファイルの読み取り、書き込み、またはロックを試行したあとでのみ、競合が検出されます。これらの競合に対するサーバーの応答もさまざまです。次に例を示します。
NFS Version 3 では、サーバーは JUKEBOX エラーを返し、クライアントはアクセス要求を停止してあとで再試行します。クライアントは、File unavailable というメッセージを表示します。
NFS Version 2 では、JUKEBOX エラーと同等のエラーが存在しないためサーバーは応答せず、クライアントは待機してから再試行します。クライアントは、NFS server not responding というメッセージを表示します。
エラーメッセージは、委託の競合が解決されたときにクリアされます。
デフォルトでは、サーバー委託は有効になっています。server_delegation パラメータを off に設定することで、委託を無効にできます。
# sharectl set -p server_delegation=off nfs
クライアントの委託にキーワードは必要ありません。NFS Version 4 コールバックデーモン nfs4cbd により、クライアント上のコールバックサービスが提供されます。このデーモンは、NFS Version 4 のマウントが有効になると自動的に起動されます。デフォルトで、クライアントは、/etc/netconfig システムファイルに一覧表示されているすべてのインターネット転送に必要なコールバック情報を提供します。クライアントで IPv6 が有効であり、クライアントの名前の IPv6 アドレスを決定できる場合、コールバックデーモンは IPv6 接続を受け入れます。
コールバックデーモンは、一時的なプログラム番号と動的に割り当てられたポート番号を使用します。この情報は、サーバーに提供され、サーバーは委託を付与する前にコールバックパスをテストします。コールバックパスが正常にテストされない場合、サーバーは委託を付与しません。外部から見ることのできる動作だけになります。
コールバック情報は NFS Version 4 要求に埋め込まれているため、サーバーは、NAT (Network Address Translation) を使用するデバイスを通してクライアントに連絡できません。また、コールバックデーモンは、動的ポート番号も使用します。したがって、ファイアウォールがポート 2049 上で通常の NFS トラフィックを有効にしている場合でも、サーバーがファイアウォールを検索できない場合があります。この場合、サーバーは委託を付与しません。
アクセス制御リスト (ACL) は、ファイルの所有者が、ファイル所有者、グループ、ほかの固有のユーザーおよびグループに関するファイルアクセス権を定義できるようにすることで、ファイルのセキュリティーを提供します。ZFS ファイルシステムでは、chmod コマンドを使用することで、ACL をサーバーおよびクライアント上で設定できます。UFS ファイルシステムの場合は、setfacl コマンドを使用できます。詳細は、chmod(1) および setfacl(1) のマニュアルページを参照してください。NFS Version 4 では、ID マッパー nfsmapid を使用して、サーバー上の ACL エントリ内のユーザー ID またはグループ ID を、クライアント上の ACL エントリ内のユーザー ID またはグループ ID にマッピングします。逆も同じです。ACL エントリのユーザーおよびグループ ID は、クライアントとサーバーの両方に存在する必要があります。
ACL および nfsmapid の詳細は、次を参照してください。
次の状態は、ID マッピングが失敗する原因になる可能性があります。
サーバー上の ACL エントリ内に存在するユーザーまたはグループをクライアント上の有効なユーザーまたはグループにマッピングできない場合、ユーザーは ACL を読み取ることはできますが、ユーザーやグループの一部が unknown と表示されます。
たとえば、この状況で ls –lv や ls –lV コマンドを発行した場合、一部の ACL エントリでグループやユーザーが unknown と表示されます。
クライアント上で設定されている ACL エントリ内のユーザーまたはグループ ID をサーバー上の有効なユーザーまたはグループ ID にマッピングできない場合、setfacl や chmod コマンドが失敗し、 Permission denied エラーメッセージを返す可能性があります。
クライアントとサーバーで nfsmapid_domain の値が一致しない場合、ID マッピングは失敗します。詳細は、NFS デーモン を参照してください。
nfsmapid_domain の値が正しく設定されていることを確認します。現在選択されている NFSv4 ドメインは、/var/run/nfs4_domain ファイル内で入手できます。
ACL エントリ内のすべてのユーザー ID およびグループ ID が NFS Version 4 のクライアントとサーバーの両方に存在することを確認します。
サーバーまたはクライアント上でユーザーまたはグループをマッピングできないかどうかを判別するには、次のスクリプトを使用します。
#! /usr/sbin/dtrace -Fs sdt:::nfs4-acl-nobody { printf("validate_idmapping: (%s) in the ACL could not be mapped!", stringof(arg0)); }