⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 631.html

📁 Jsp精华文章合集,JSP方面各种知识介绍
💻 HTML
📖 第 1 页 / 共 2 页
字号:

<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信息&lt;br&gt;<br>    NFS write error 13 on host A fh 1cc0006 2 a0000 6db28 0 a0000 2 0<br><br>    Solaris 2.x信息&lt;br&gt;<br>    NFS write error on host A Permission denied.&lt;br&gt;<br>    File: userid=0, groupid=0&lt;br&gt;<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 &lt;---- File system id的10进制表示<br>80000C <br><br>149780 &lt;---- 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 &lt;stdio.h&gt;<br>#include &lt;fcntl.h&gt;<br>#include &lt;dirent.h&gt;<br>#include &lt;sys/types.h&gt;<br>#include &lt;sys/statvfs.h&gt;<br>#include &lt;sys/mnttab.h&gt;<br>#include &lt;sys/mntent.h&gt;<br>#include &lt;sys/stat.h&gt;<br>#include &lt;sys/fs/ufs_fs.h&gt;<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 + -