NFS 版本 4 中的客户机恢复
NFS 版本 4 协议为有状态协议。如果客户机和服务器都保留有关以下内容的当前信息,协议即为有状态协议。
打开的文件
出现故障(如服务器崩溃)时,客户机和服务器会协同工作,重新建立故障前已存在的打开状态和锁定状态。
服务器崩溃并重新引导时,会丢失其状态。客户机检测到服务器已经重新引导后,将启动帮助服务器重建其状态的进程。此进程称为客户机恢复,因为由客户机引导此进程。
客户机发现服务器已经重新引导后,便会立即暂停其当前活动并启动客户机恢复进程。启动恢复进程时,系统错误日志
/var/adm/messages
中会显示如下消息。
NOTICE: Starting recovery server basil.example.company.com
在恢复进程中,客户机会向服务器发送有关客户机以前状态的信息。但是请注意,在此期间,客户机不会向服务器发送任何新请求。任何打开文件或设置文件锁定的新请求都必须等到服务器完成其恢复期之后才能继续进行。
客户机恢复进程完成时,系统错误日志
/var/adm/messages
中会显示以下消息。
NOTICE: Recovery done for server basil.example.company.com
现在,客户机已经成功地将其状态信息发送给服务器。不过,尽管此客户机已经完成了此进程,但是其他客户机可能尚未完成将其状态信息发送给服务器这一进程。因此,在一段时间内,服务器不会接受任何打开或锁定请求。指定这段时间(称为宽延期)旨在允许所有客户机完成其恢复。
在宽延期内,如果客户机尝试打开任何新文件或建立任何新锁定,服务器都会拒绝请求并显示
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 70): file : filename
请注意,数字
70
仅是一个示例。
如果在恢复过程中重新建立文件锁定失败,则会显示以下错误消息。
NOTICE: nfs4_send_siglost: pid PROCESS-ID lost
lock on server SERVER-NAME
在这种情况下,会向进程发送
SIGLOST
信号。
SIGLOST
信号的缺省操作是终止此进程。
要从此状态恢复,必须重新启动所有在失败时打开文件的应用程序。请注意,可能会出现以下情况。
一些没有重新打开文件的进程可能会收到
I/O
错误消息。
在恢复失败之后已重新打开文件或执行打开操作的其他进程可顺利访问文件。
因此,一些进程可以访问其他进程无法访问的特定文件。
NFS 版本 4 中的
OPEN
共享支持
NFS 版本 4 协议提供了几种文件共享模式,客户机可以使用这些模式控制其他客户机对文件的访问。客户机可以指定以下内容:
DENY_NONE
模式,用于允许其他客户机对文件进行读写访问。
DENY_READ
模式,用于拒绝其他客户机对文件进行读取访问。
DENY_WRITE
模式,用于拒绝其他客户机对文件进行写入访问。
DENY_BOTH
模式,用于拒绝其他客户机对文件进行读写访问。
Solaris NFS 版本 4 服务器完全实现了这些文件共享模式。因此,如果客户机尝试打开文件的方式与当前共享模式冲突,则服务器会通过使操作失败来拒绝此尝试。如果这类尝试在打开或创建操作开始时失败,则 NFS 版本 4 客户机会收到一条协议错误消息。此错误会映射为应用程序错误
EACCES
。
尽管此协议提供了几种共享模式,但目前 Solaris 中的打开操作不提供多种共享模式。打开文件时,Solaris NFS 版本 4 客户机只能使用
DENY_NONE
模式。
另外,尽管
fcntl
系统调用使用
F_SHARE
命令来控制文件共享,但是
fcntl
命令无法在 NFS 版本 4 中正常实现。如果在 NFS
版本 4 客户机上使用这些
fcntl
命令,则客户机会向应用程序返回一条
EAGAIN
错误消息。
NFS 版本 4 中的委托
NFS 版本 4 为委托同时提供客户机支持和服务器支持。委托是服务器用于将文件管理委托给客户机的一种技术。例如,服务器可以授予客户机读取委托或写入委托。读取委托可以同时授予多台客户机,因为这些读取委托不会彼此冲突。写入委托只能授予一台客户机,因为写入委托会与其他任何客户机进行的任何文件访问相冲突。虽然客户机拥有写入委托,但是它不会向服务器发送各种操作,因为客户机保证具有对文件的独占访问权限。同样,客户机在拥有读取委托时也不会向服务器发送各种操作。这是因为服务器保证任何客户机都不能以写入模式打开文件。通过委托,可显著减少服务器和客户机之间针对被委托文件的交互。因此,可降低网络通信流量,并且提高客户机和服务器的性能。但是请注意,性能提高的程度取决于应用程序使用的文件交互的类型以及网络和服务器的拥塞量。
是否授予委托完全由服务器决定。客户机不会请求委托。服务器可根据文件的访问模式来决定是否授予委托。如果几台不同的客户机最近以写入模式访问了文件,则服务器可能不会授予委托。原因是此访问模式表明将来可能会发生冲突。
当客户机访问文件的方式与当前授予此文件的委托不一致时,便会发生冲突。例如,如果一台客户机拥有对文件的写入委托,同时另一台客户机打开此文件来进行读取或写入访问,则服务器会撤销第一台客户机的写入委托。同样,如果一台客户机拥有读取委托,同时另一台客户机打开同一个文件进行写入,则服务器会撤销读取委托。请注意,在这两种情况下都不会将委托授予第二台客户机,因为此时存在冲突。发生冲突时,服务器会使用回调机制来联系当前拥有委托的客户机。收到此回调后,客户机会向服务器发送文件的更新状态并返回委托。如果客户机无法对重新调用做出响应,则服务器会撤销委托。在此类情况下,服务器会拒绝客户机对此文件进行的所有操作,客户机将已请求的操作报告为失败。通常,这些失败会作为
I/O
错误报告给应用程序。要从这些错误中恢复,必须关闭文件,然后再重新打开。当客户机和服务器之间存在网络分区并且客户机拥有委托时,撤销委托会失败。
请注意,一台服务器不能解决对其他服务器上存储的文件的访问冲突。因此,NFS 服务器仅解决它自己存储的文件的冲突。此外,要响应由运行各种 NFS 版本的客户机导致的冲突,NFS 服务器只能对运行 NFS 版本 4 的客户机启动重新调用。NFS 服务器不能对运行早期 NFS 版本的客户机启动重新调用。
检测冲突的进程会有所变化。例如,与 NFS 版本 4 不同,因为版本 2 和版本 3 不包括打开过程,所以仅会在客户机尝试读取、写入或锁定文件之后检测冲突。服务器对这些冲突的响应也会有所不同。例如:
对于 NFS 版本 3,服务器会返回
JUKEBOX
错误消息,这会导致客户机停止访问请求并稍后重试。客户机会输出消息
File unavailable
。
对于 NFS 版本 2,因为不存在与
JUKEBOX
错误消息等效的消息,所以服务器不做任何响应,这会导致客户机等待然后再重试。客户机会输出消息
NFS server not responding
。
解决了委托冲突之后,便不会存在这些情况。
回调守护进程使用临时的程序编号以及动态指定的端口号。此信息提供给服务器,服务器会在授予任何委托之前测试回调路径。如果回调路径测试不成功,则服务器不会授予委托,这是唯一可从外部看到的行为。
请注意,因为回调信息嵌在 NFS 版本 4 请求中,所以服务器不能通过使用网络地址转换 (Network Address Translation, NAT) 的设备来联系客户机。另外,回调守护进程还会使用动态端口号。因此,即使防火墙在端口 2049 上启用了正常的
NFS 流量,服务器可能仍然无法遍历防火墙。在此类情况下,服务器不会授予委托。
启动过程中,还会协商传输协议。缺省情况下,将选择客户机和服务器同时支持的第一个面向连接的传输。如果此选择未成功,则使用第一个可用的无连接传输协议。
/etc/netconfig
中列出了系统支持的传输协议。TCP 是该发行版支持的面向连接的传输协议。UDP 是无连接传输协议。
如果 NFS 协议版本和传输协议都是通过协商确定的,则 NFS 协议版本优先于传输协议。使用 UDP 的 NFS 版本 3 协议比使用 TCP
的 NFS 版本 2 协议具有更高的优先级。可以使用
mount
命令手动选择 NFS 协议版本和传输协议。请参见
mount_nfs
(1M)
手册页。在大多数情况下,允许协商选择最佳选项。