📄 rfc1094.txt
字号:
};
"sattr"结构包含着可以从客户端设置的文件的属性。这些字段与上面的"fattr"中的字段的含义是相同的。"size"值为0意味着文件将被截短。一个 -1的值意味着这个字段将被忽略。
2.3.7. filename(文件名)
typedef string filename<MAXNAMLEN>;
"filename"用来传送文件名或者路径名的组成部分。
2.3.8. path(路径)
typedef string path<MAXPATHLEN>;
"path"是一个路径名。服务器把它作为一个没有内部结构的字符串,但是对客户端来说它是文件系统树中的节点的名字。
2.3.9. attrstat(属性状态)
union attrstat switch (stat status) {
case NFS_OK:
fattr attributes;
default:
void;
};
"attrstat"结构是一个公共的过程结果。它包含着一个"status",如果这个调用成功,它将也包含操作作用于那个文件的属性。
2.3.10. diropargs(目录操作参数)
struct diropargs {
fhandle dir;
filename name;
};
"diropargs"结构使用在目录属性操作中。 "dir" 是在其中寻找文件"name"的那个目录。一个目录操作影响这个目录。
2.3.11. diropres(目录操作结果)
union diropres switch (stat status) {
case NFS_OK:
struct {
fhandle file;
fattr attributes;
} diropok;
default:
void;
};
在"diropres"中返回目录操作的结果。如果这个调用成功,与这个文件相关的新文件句柄"file"和文件属性"attributes"将连同"status"一起返回。
3. NFS实现中的问题
NFS协议设计为允许不同的操作系统共享文件。但是,因为它在UNIX环境中设计,所以,许多操作与UNIX文件系统的操作语义相似。这一节讨论实现中特别的细节和语义的问题。
3.1 服务器/客户端 的关系
NFS协议被设计为让服务器尽可能的简单和通用。有时候如果客户端想实现复杂的文件系统语义,服务器的简单性可能是一个难题。
例如,一些操作系统允许删除打开的文件。一个进程能够打开文件,当文件打开的时候,从目录中删除它。只要进程保持文件打开,这个文件就可以被读写,即使这个文件在文件系统中没有名字。对于无状态服务器来说,实现这些语义是不可能的。客户端可以使用一些技巧,诸如在删除时重命名这个文件,只在它关闭的时候删除它。我们相信服务器提供了足够的功能在客户端上实现大多数文件系统的语义。
每一个NFS客户端也是一个潜在的服务器,远程和本地安装的文件系统可以自由的混合在一起。当客户端浏览远程文件系统的目录树,到达在服务器上另一个远程系统的安装点的时候,将会出现一些有趣的问题。要允许服务器跟随第二个远程安装就需要循环检测,服务器查找和用户重新生效。代替的做法是,我们决定不让客户端越过服务器的安装点。.当客户端在一个服务器已经安装了文件系统的目录中查询的时候,客户端将看见下面的目录而不是安装的目录。
例如,如果服务器有一个叫做"/usr"的文件系统,把另一个文件系统安装在"/usr/src"上,如果客户端安装了"/usr",它将看不到"/usr/src"的安装版本。客户端能做远程安装以配合服务器的安装点保持服务器的视图。在这个例子中,客户端应该除了安装"/usr"之外,还要安装"/usr/src",即使它们是来自同一台服务器。
3.2 路径名解析
路径名总是在客户端解析的规则有点复杂。例如,符号链接在不同的客户端可以有不同的解释。对于非UNIX实现的另一个共同的问题就是路径".."的专门的解释是给定的目录的父目录。此协议的下一个修订版将使用一个明确的标志指示父目录。
3.3 许可问题
严格的讲,NFS协议没有定义服务器使用的许可权限检查。但是,也希望使用AUTH_UNIX类型认证这一基础的保护机制作正常的操作系统许可权限检查,服务器得到客户的有效"uid",有效"gid"和每次调用上的组,使用它们来检查许可。使用这种方法产生的问题可以用一些有趣的途径来解决。
使用"uid" 和 "gid"暗示着客户端和服务器分享相同的"uid"列表。每一对服务器和客户端必须有相同的用户到"uid",组到"gid"的映射。因为每一个客户端也可能是一台服务器,这意味着整个网络共享相同的"uid/gid"空间。AUTH_DES(和NFS协议的下一个修订版)使用字符串来代替数字,但是仍有复杂的问题要解决。
由于打开操作有状态,所以产生了另一个问题。大多数操作系统在打开文件的时候检查许可权限,在每一次读写请求的时候检查文件是否打开。在无状态的服务器中,服务器没有办法知道文件是否打开,必须在每次读写调用的时候检查许可权限。在一个本地文件系统上,用户可以打开文件,然后改变权限不允许别人接触它,但是仍然能够写文件,因为文件是打开的。相反,在远程文件系统上,写操作将失败。为了避免这种问题,服务器的许可检查算法将允许文件的所有者访问文件,而不管许可的设置。
在从网络中的文件上进行页面调度的时候,也会出现相似的问题。操作系统在打开一个文件进行页面调度之前,总是检查执行许可权限,然后从打开的文件中读取块。文件可能没有读许可权限,但是在文件打开后,这就不是一个问题了。NFS服务器不能区分在正常文件读和页面调入请求读之间的区别。为了使这个可以工作,如果在调用中被给的"uid"在文件上有执行或者读许可权限,服务器将允许读文件。
在大多数操作系统中,一个特别的用户(在UNIX上,用户ID为0)有访问所有文件的权限,而不管文件中的所有权和设定的许可权限。"super-user"权限在服务器上不可能被允许, 因为在自己工作站上的任何具有超级用户权限的人都能访问所有的远程文件。UNIX服务器在访问检查前,默认把用户ID 0 映射为 -2。这个工作在NFS的根文件系统中例外,在那里超级用户访问不能避免。
3.4 RPC信息
认证
NFS服务使用AUTH_UNIX, AUTH_DES 或者AUTH_SHORT类型的认证,
在NULL过程中例外,在那里AUTH_NONE也被允许。
传输协议
NFS通常由UDP支持。
端口号
NFS协议当前使用UDP端口号2049。这不是一个正式分配的端口号,所以,
这个协议的后继版本使用RPC的“端口映射”工具。
3.4 XDR结构的尺寸
这里有一些使用在此协议中不同的XDR结构的尺寸,用十进制字节给出。
/*
* 在读写请求中的数据的最大字节数。
*/
const MAXDATA = 8192;
/*在路径参数中的最大字节数 */
const MAXPATHLEN = 1024;
/*在文件名参数中的最大字节数*/
const MAXNAMLEN = 255;
/*被READDIR 传送的"cookie"字节数的大小*/
const COOKIESIZE = 4;
/*不透明文件句柄的字节数的大小*/
const FHSIZE = 32;
3.6 设置RPC的参数
不同的文件系统参数和选项应该在安装的时候设置。安装协议在附录中描述。例如,象“硬”安装一样,“软”安装也被提供。当RPC操作失败(在给出一个重传的选项号后),软安装文件系统返回错误,而硬安装文件系统一直继续重传。最大的传输尺寸依赖于实现。对于在一个本地网的有效操作来说,通常使用8192字节的数据。这可能导致下层的分段(诸如在IP层)。既然一些网络接口不允许这样的包,对于在低速网络、主机上的操作,或者通过网关的操作,512或1024字节总是提供较好的结果。
客户机和服务器可能需要把当前的操作保存在缓冲区中,以帮助避免因为非幂等的操作产生的问题。例如,如果传输协议丢失了删除文件操作的响应,在重传的时候,服务器可能返回一个NFSERR_NOENT来代替NFS_OK。但是,如果服务器保持上次的请求操作和结果,它可能返回正确的成功的代码。当然,服务器在重传之间可能崩溃、重起。但是一块很小的缓冲区(甚至只是容纳一个条目)将解决大部分的问题。
附录A 安装协议定义
A.1. 简介
安装协议与NFS协议分离,但是与NFS协议相关。它提供了操作系统特定的服务来扩展NFS的功能:查询服务器路径名,使用户身份有效,检查访问权限。客户端使用安装协议得到第一个文件句柄,这允许客户进入一个远程的文件系统。
安装协议与NFS协议保持分离,使得在不改变NFS服务器协议的情况下很容易加进新的访问检查和确认的方法。
注意:这个协议的定义暗示着服务器有状态,因为服务器保持着一个客户端安装请求的列表。安装列表信息对客户机或者服务器的功能没有危害性。仅仅建议在服务器出现故障时,给客户机可能的警告。
安装协议的第一版与NFS协议的第二版一起使用,在两个协议中唯一通信的信息是"fhandle"结构。
A.2 RPC信息
认证
安装服务仅使用AUTH_UNIX 和 AUTH_NONE类型的认证
传输协议
安装服务被UDP和TCP中支持。
端口号
与服务器的端口映射器协商,来发现安装服务注册的端口号。
A.3 XDR结构的尺寸
这里有使用在此协议中不同的XDR结构的尺寸,用十进制表示。
/* 路径名参数的最大字节数*/
const MNTPATHLEN = 1024;
/*一个名字参数的最大字节数 */
const MNTNAMLEN = 255;
/* 不透明文件句柄的字节数*/
const FHSIZE = 32;
A.4 基本数据类型
这一节描述使用在安装协议中的数据类型。在许多情况下它们与使用在NFS中的数据类型相似。
A.4.1. fhandle
typedef opaque fhandle[FHSIZE];
"fhandle"类型是服务器传递给客户端的文件句柄。所有文件操作都使用文件句柄来引用文件或者目录。文件句柄包含着服务器需要的区分单个文件的信息。
这与NFS协议第二版中的"fhandle"XDR定义一样;见在 "基本数据类型"之中的"2.3.3. fhandle"。
A.4.2. fhstatus
union fhstatus switch (unsigned status) {
case 0:
fhandle directory;
default:
void;
}
"fhstatus"类型是一个联合结构。如果返回的"status"为0,调用执行成功,接着的是给"directory"分配的文件句柄。一个非0 值表示一些种类的错误。在这种情况下,status是一个UNIX错误号。
A.4.3. dirpath
typedef string dirpath<MNTPATHLEN>;
"dirpath"类型是一个目录的服务器的路径名。
A.4.4. name
typedef string name<MNTNAMLEN>;
"name"类型是一个使用在不同名字中的二进制串。
A.5. 服务器过程
下面的部分定义了安装服务器提供的RPC过程。
/*
*安装程序的协议定义
*/
program MOUNTPROG {
/*
*安装协议的第一版与NFS协议的第二版使用在一起。
*/
version MOUNTVERS {
void MOUNTPROC_NULL(void) = 0;
fhstatus MOUNTPROC_MNT(dirpath) = 1;
mountlist MOUNTPROC_DUMP(void) = 2;
void MOUNTPROC_UMNT(dirpath) = 3;
void MOUNTPROC_UMNTALL(void) = 4;
exportlist MOUNTPROC_EXPORT(void) = 5;
} = 1;
} = 100005;
A.5.1. 不作工作
void MNTPROC_NULL(void) = 0;
这个过程什么也不作,在所有的RPC服务中使用它来允许服务器响应测试和定时。
A.5.2 加入安装条目
fhstatus MNTPROC_MNT(dirpath) = 1;
如果响应状态"status"是0,那么响应的"directory"包含着目录"dirname"的文件句柄。这个文件句柄可能使用在NFS协议中。这个过程也在客户安装的"dirname"安装列表中加一个新的项目。
A.5.3 返回安装条目
struct *mountlist {
name hostname;
dirpath directory;
mountlist nextentry;
};
mountlist MNTPROC_DUMP(void) = 2;
返回一个远程安装文件系统的列表。"mountlist"对每一对"hostname" 和"directory"都包含着一个条目。
A.5.4. 删除安装条目
void MNTPROC_UMNT(dirpath) = 3;
从输入"dirpath"中删除安装列表条目
A.5.5. 删除所有的安装条目
void MNTPROC_UMNTALL(void) = 4;
为客户端删除所有安装列表的条目
A.5.6. 返回输出列表
struct *groups {
name grname;
groups grnext;
};
struct *exportlist {
dirpath filesys;
groups groups;
exportlist next;
};
exportlist MNTPROC_EXPORT(void) = 5;
返回一组可变数目的输出列表条目。每一个条目包含着文件系统名和一个被允许导入的组列表。文件系统名在"filesys"当中,组名在列表"groups"中。
注意:输出列表应该包含关于文件系统状态的更多的信息,例如只读标志。
作者地址
Bill Nowicki
Sun Microsystems, Inc.
Mail Stop 1-40
2550 Garcia Avenue
Mountain View, CA 94043
Phone: (415) 336-7278
Email: nowicki@SUN.COM
RFC1094 NFS: Network File System Protocol Specification RFC1094 网络文件系统协议
1
1
RFC文档中文翻译计划
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -