📄 631.html
字号:
<STYLE type=text/css>
<!--
body,td { font-size:9pt;}
hr { color: #000000; height: 1px}
-->
</STYLE>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD><TITLE>FAQ汇萃 >> solaris 专栏 >> 钱飞老师的solaris技术问答(5)-NFS暗号信息的解析方法</title>
</head>
<body >
<p><IMG SRC="../image/jsp001_middle_logo.gif" WIDTH="180" HEIGHT="60" BORDER=0 ALT=""></p>
<table width=100% bgcolor="#cccccc" align=center cellpadding="2" cellspacing="0" border=1 bordercolorlight="#000000" bordercolordark="#FFFFFF">
<tr bgcolor="#EFF8FF"><td>
<a href=http://www.jsp001.com/list_thread.php?int_attribute=1>FAQ汇萃</a>
>> <a href=http://www.jsp001.com/list_thread.php?forumid=39&int_attribute=1>solaris 专栏</a>
>> 钱飞老师的solaris技术问答(5)-NFS暗号信息的解析方法 [<a href=http://www.jsp001.com/forum/showthread.php?goto=newpost&threadid=631>查看别人的评论</a>]<br>
<hr><p>由 fei 发布于: 2001-03-06 13:55</p><p> </p><p>问:在我们的局部网中使用着NFS,NFS的服务器由运行Solaris 2.X系统的SUN工作 站来担当。但最近频繁地出现以下信息。 <br><br> <br> SunOS 4.1.x信息<br><br> NFS write error 13 on host A fh 1cc0006 2 a0000 6db28 0 a0000 2 0<br><br> Solaris 2.x信息<br><br> NFS write error on host A Permission denied.<br><br> File: userid=0, groupid=0<br><br> (file handle: 1cc0006 2 a0000 6db28 0 a0000 2 0)<br><br>仅仅依靠这些信息我们还无法断定出错原因,需要对信息加以解析以便定位。 在全部由SunOS 4.1.x系统所构成的网络中,NFS服务器上事先启动rpc.showfhd 常驻进程,当出现类似错误信息时,可以在NFS客户机上执行showfh命令,从错 误信息调查相应的文件名。但在Solaris 2.X上没有这类命令,有没有办法可以 进行类似调查? <br>答:showfh命令的存在很少为人所知。用该命令的确可以从NFS error信息来调查N FS服务器上的出错文件名。showfh命令对于 NFS纠错和性能调节来说有着相当 重要的作用。但在Solaris 2.X上没有这类命令的确让人感到遗憾(据SUN称没 有相应的替换命令)。光遗憾亦与事无补,让我们自己来挑战一下这个问题吧。 <br><br>1. 来自NFS的暗号文 <br><br>众所周知,在UNIX系统上存取文件或执行命令时,需要用到UNIX PATH的概念。即便是对NFS文件系统所装载的远程文件系统,用户也不需要做特殊的考虑,仍可以用 UNIX PATH来进行处理。 <br><br>但在NFS内部则完全不是这么简单。NFS具有很强的柔软性,在设计上并不仅仅针对UNIX系统,NFS服务器可以不是UNIX计算机。正是由于考虑到了这一点,在NFS的内部才不采用UNIX PATH。为了表示特定的文件,NFS内部采用了FILE HANDLE 的概念(以下简称为fh)。 <br><br>在NFS error信息中包有含出错文件信息。但由于NFS error为内部错误,因此这种信息是以fh的形式来表示的。然而,fh信息对于习惯了UNIX PATH的用户来说跟暗号文一样,很难理解。例如,在上述问题中NFS error信息中便含有以下fh值: <br><br>1cc0006 2 a0000 6db28 0 a0000 2 0 <br><br>2. 知彼求策 <br><br>fh信息的这些数字到底表示了什么呢? <br><br>首先我们可以看到该信息有8个字段所构成。但这8个字段意味着什么,笔者也曾查阅了许多资料和手册仍不知所云。估计这可能与fh之本身性质有关。 <br><br>其实,fh是只有NFS服务器才能理解的一种暗号。NFS客户机在调用NFS服务器上的文件时,首先从NFS服务器接收fh,然后在读写该文件时用fh来定位NFS服务器上的该文件之所在。因此,在NFS客户机上并不需要理解所收到的fh之内容。 <br><br>另外,如上所述,NFS服务器不一定非UNIX计算机不可。如果NFS服务器为SUN工作站的话,系统在对文件进行定位时可以利用inode号码,但在非UNIX计算机上可能根本就不存在inode的概念。因此可知,完全没有必要决定fh的信息格式。只要有一个大致的标准,按照该标准NFS服务器只要能够按照自己易懂的方法决定fh的内容即可。 <br><br>NFS 服务器根据版本不同存在着差异。不确定的要素太多也许正是无法文件化的原因所在。 <br><br>您的问题是针对SUN工作站而言的,因此,我们需要花一些力气来理解一下SUN工作站上的NFS服务器的fh内容。 <br><br>3. 揭开谜底 <br><br>这里需要一些有关C语言和SunOS的基本知识。为了追求线索,让我们先用最笨,但也可能是最简单的方法来查看一下SUN的fh含义。 <br><br>首先,逐个的查看一下与NFS有关的C程序HEAD文件。 <br><br>% view /usr/include/nfs/* <br><br>工夫不负有心人,与fh格式相关连的基本定义好象是由/usr/include/nfs/nfs.h中的下述模块所给出。 <br><br> #define NFS_FHSIZE 32<br> #define NFS_FHMAXDATA ((NFS_FHSIZE - sizeof(struct fhsize) + 8)/2)<br> <br> struct svcfh {<br> fsid_t fh_fsid; /* filesystem id */<br> u_short fh_len; /* file number length */<br> char fh_data[NFS_FHMACDATA]; /* and data */<br> u_short fh_xlen; /* export file number length */<br> char fh_xdata[NFS_FHMACDATA];/* and data */<br> };<br><br>但是,光靠这点儿信息还远远不够,还需要对NFS服务器与客户机之间的具体信息交换来进行调查,从网络上截取NFS信息包。 <br>在Solaris上可以用snoop命令来观察网络状况。 <br><br>% snoop -v rpc nfs <br><br> NFS: ------------------ entry #7<br> NFS: File ID = 149780<br> NFS: Name = index.htm<br> NFS: Cookie = 164<br> NFS: Post-operation attributes: <br> NFS: File type = 1 (Regular File)<br> NFS: Mode = 0644<br> NFS: Setuid = 0, Setgid = 0, Sticky = 0<br> NFS: Owner's permissions = rw-<br> NFS: Group's permissions = r--<br> NFS: Other's permissions = r--<br> NFS: Link count = 1, User ID = 0, Group ID = 1<br> NFS: File size = 5465, Used = 98304<br> NFS: Special: Major = 0, Minor = 0<br> NFS: File system id = 8388620, File id = 149780<br> NFS: Last access time = 20-Oct-96 23:13:00.420002000 GMT<br> NFS: Modification time = 16-Jul-96 03:23:41.569999000 GMT<br> NFS: Attribute change time = 16-Jul-96 03:23:41.569999000 GMT<br> NFS: <br> NFS: File handle = 0080000C00000002000A000000024914<br> NFS: 62DA8A7E000A00000001EF07788C7F8A<br><br>从snoop命令的执行结果中我们可以得到许多提示。首先,我们已经知道,当出现 NFS error时,fh信息曾被分割成8个字段。因此,让我们将上述结果中fh信息值分成8个等份,可见, <br> <br> File handle = 0080000C 00000002 000A0000 00024914<br> 62DA8A7E 000A0000 0001EF07 788C7F8A<br><br>在UNIX系统上,本地硬盘上的文件是由inode来管理的。inode在文件系统中具有一个唯一的号码。同样文件系统也具有一个类似的唯一号码,称之为文件系统号码。因此,只要能够定位文件系统及inode号码,即可定位文件名。在上述结果中,文件系统id(File system id)及inode号码(File id)分别为: <br>File system id = 8388620, File id = 149780 <br><br>由于这里的“File system id”和“File id”均为10进制表示,为进行比较,先将其转换为16进制表示。 <br><br>% bc<br>obase=16 <br><br>8388620 <---- File system id的10进制表示<br>80000C <br><br>149780 <---- File id的10进制表示<br>24914 <br><br>与上述结果相比较可以发现,"File system id"为fh的第一字段值,"File id"为第四字段值! <br><br>4. 新命令诞生 <br><br>我们最终的目标是定位出错文件,仅仅知道了上述"File system id"和"File id" 还不行,还必须确定相应的UNIX PATH。 <br><br>在Solaris上“File system id”可以从/etc/mnttab文件中得到。用程序读取该文件时,可以使用getmntent(3C)函数。/etc/mnttab文件内含有以下定义: <br><br>/dev/dsk/c0t1d0s4 /mnt ufs suid,rw,dev=80000c 852450814 <br><br>这里,dev=XXX处定义值即为“File system id”的16进制表示。 通过比较"File system id"和"File id"便可定位文件名。具体的定位程序如下。 <br><br> <br>------------------------------------------------------------------------<br>/* findfh.c<br> * 从NFS的fh (File Handle) 定位UNIX PATH。<br> * 执行时请在命令行上指定NFS error信息中的NFS fh值(8字段16进制) 。<br> */<br>#include <stdio.h><br>#include <fcntl.h><br>#include <dirent.h><br>#include <sys/types.h><br>#include <sys/statvfs.h><br>#include <sys/mnttab.h><br>#include <sys/mntent.h><br>#include <sys/stat.h><br>#include <sys/fs/ufs_fs.h><br><br>char *find_inode(char *, int) ;<br><br>main(int argc, char **argv)<br>{<br> int ret ;<br> char *fn ;<br> FILE *fp ;<br> u_long ino ;<br> u_long fsid ;<br> struct mnttab mnt ;<br> struct statvfs vfs ;<br><br> if(argc != 9) {<br> fprintf(stderr, "Usage: %s nfs_fh\n", argv[0]) ;<br> exit(1) ;<br> }<br><br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -