使用N F S,客户可以透明地访问服务器上的文件和文件系统。这不同于提供文件传输的F T P(第2 7章)。F T P会产生文件一个完整的副本。 N F S只访问一个进程引用文件的那一部分,并且N F S的一个目的就是使得这种访问透明。这就意味着任何能够访问一个本地文件的客户程序不需要做任何修改,就应该能够访问一个 N F S文件。
N F S是一个使用Sun RPC构造的客户服务器应用程序。 N F S客户通过向一个N F S服务器发送R P C请求来访问其上的文件。尽管这一工作可以使用一般的用户进程来实现—即N F S客户可以是一个用户进程,对服务器进行显式调用。而服务器也可以是一个用户进程—因为两个理由,N F S一般不这样实现。首先,访问一个 N F S文件必须对客户透明。因此, N F S的客户调用是由客户操作系统代表用户进程来完成的。第二,出于效率的考虑, N F S服务器在服务器操作系统中实现。如果 N F S服务器是一个用户进程,每个客户请求和服务器应答(包括读和写的数据)将不得不在内核和用户进程之间进行切换,这个代价太大。
本节中,我们考察在R F C 1 0 9 4中说明的第2版的NFS [Sun Microsystems 1988b]。[ X / O p e n 1991] 中给出了Sun RPC、X D R和N F S的一个更好的描述。 [Stern 1991] 给出了使用和管理N F S的细节。第3版的N F S协议在1 9 9 3年发布,我们在2 9 . 7节中对它做一个简单的描述。
图2 9 - 3显示了一个N F S客户和一个N F S服务器的典型配置,图中有很多地方需要注意。
大多数的U n i x主机可以作为一个N F S客户,一个N F S服务器,或者两者都是。大多数P C机的实现(M S - D O S)只提供了N F S客户实现。大多数的I B M大型机只提供了N F S服务器功能。N F S实际上不仅仅由N F S协议组成。图2 9 - 4显示了N F S使用的不同R P C程序。
在这个图中,程序的版本是在SunOS 4.1.3中使用的。更新的实现提供了其中一些程序更新的版本。例如,Solaris 2.2还支持端口映射器的第3版和第4版,以及安装守护程序的第2版。SVR4支持第3版的端口映射器。
在客户能够访问服务器上的文件系统之前, N F S客户主机必须调用安装守护程序。我们在下面讨论安装守护程序。
加锁管理程序和状态监视器允许客户锁定一个 N F S服务器上文件的部分区域。这两个程序独立于N F S协议,因为加锁需要知道客户和服务器的状态,而 N F S本身在服务器上是无状态的(下面我们对N F S的无状态会介绍得更多)。[X/Open 1991] 的第9, 10和11章说明了使用加锁管理程序和状态监视器进行 N F S文件锁定的过程。
N F S中一个基本概念是文件句柄 (file handle)。它是一个不透明( o p a q u e )的对象,用来引用服务器上的一个文件或目录。不透明指的是服务器创建文件句柄,把它传递给客户,然后客户访问文件时,使用对应的文件句柄。客户不会查看文件句柄的内容—它的内容只对服务器有意义。
每次一个客户进程打开一个实际上位于一个 N F S服务器上的文件时,N F S客户就会从N F S服务器那里获得该文件的一个文件句柄。每次 N F S客户为用户进程读或写文件时,文件句柄就会传给服务器以指定被访问的文件。
一般情况下,用户进程不会和文件句柄打交道—只有N F S客户和N F S服务器将文件句柄传来传去。在第2版的N F S中,一个文件句柄占据3 2个字节,第3版中增加为6 4个字节。U n i x服务器一般在文件句柄中存储下面的信息:文件系统标识符(文件系统最大和最小的设备号),i - n o d e号(在一个文件系统中唯一的数值)和一个 i - n o d e的生成码(每当一个i-node被一个不同的文件重用时就改变的数值)。
客户必须在访问服务器上一个文件系统中的文件之前,使用安装协议安装那个文件系统。一般情况下,这是在客户主机引导时完成的。最后的结果就是客户获得服务器文件系统的一个文件句柄。 图2 9 - 5显示了一个U n i x客户发出m o u n t( 8 )命令所发生的情况,它说明一个N F S的安装过程。
依次发生了下面的动作。
上述实现技术将所有的安装处理,除了客户机上的 m o u n t系统调用,都放在用户进程中,而不是放在内核中。我们显示的三个程序—m o u n t命令、端口映射器和安装守护程序—都是用户进程。 作为一个例子,在我们的主机 s u n(一个N F S客户机)上执行:
sun # mount -t nfs bsdi:/usr /nfs/bsdi/usr
这个命令将主机 b s d i(一个N F S服务器)上的 / u s r目录安装成为本地文件系统 / n f s / b s d i /u s r。图2 9 - 6显示了结果。
当我们引用客户机s u n上的/nfs/bsdi/usr/rstevens/hello.c 文件时,实际上引用的是服务器b s d i上的文件/ u s r / r s t e v e n s / h e l l o . c。
现在我们描述N F S服务器提供的1 5个过程(使用的个数与N F S过程的实际个数不一样,因为我们把它们按照功能分了组)。尽管N F S被设计成可以在不同的操作系统上工作,而不仅仅是U n i x系统,但是一些提供 U n i x功能的过程可能不被其他操作系统支持(例如硬链接、符号链接、组的属主和执行权等)。[Stevens 1992]的第4章包含了U n i x文件系统其他的一些信息,其中有些被N F S采用。
N F S最初是用 U D P写的,所有的厂商都提供了这种实现。最新的一些实现也支持 T C P。T C P支持主要用于广域网,它可以使文件操作更快。 N F S已经不再局限于局域网的使用。当从L A N转换到WA N时,网络的动态特征变化得非常大。往返时间( round-trip time)变动范围大,拥塞经常发生。 WA N的这些特征使得我们考虑使用具有 T C P属性的算法—慢启动,但是可以避免拥塞。既然 U D P没有提供任何类似的东西,那么在 N F S客户和服务器上加进同样的算法或者使用T C P。
伯克利实现的Net/2 NFS支持U D P或者T C P。[Macklem 1991]描述了这个实现。让我们看一下使用T C P有什么不同。
/ n f s / b s d i / u s r / r s t e v e n s
和/ n f s / b s d i / u s r / s m i t h
下所有文件的引用将共享同样的 T C P连接。随着时间的流逝,另外一些厂商也计划支持 T C P上的N F S。