19 FreeBSD CURRENTFreeBSD STABLE

19.1 概要

FreeBSD是个持续发展中的操作系统。对于那些喜欢追逐技术前沿的用户而言,有几个简单的方法可以使你的系统和最新发展中的版本保持同步。注意:并非每个人都适合这么做!这章将帮助你决定到底应该要追随发展中的版本,还是要使用稳定版。

读完这章,你将了解到这些:

             两种不同的开发分支:FreeBSD-STABLEFreeBSD-CURRENT

             如何确保你的系统保持与CVSupCVSCTM同步。

             如何使用make world来重建和重新安装整个基本系统。

读这章之前,你需要了解:

             正确设置你的网络连接(第17章)。

             知道如何安装第三方软件(第4章)。

19.2 FreeBSD-CURRENT vs. FreeBSD-STABLE

FreeBSD有两个开发分支:FreeBSD-CURRENT FreeBSD-STABLE。这章将介绍有关如何确保你的系统与每个相关的目录树保持同步。首先讨论FreeBSD-CURRENT,然后是FreeBSD-STABLE

19.2.1 是否使用FreeBSD-CURRENT

正如你读到的,FreeBSD-CURRENT是开发分支中比较追求技术前沿的一个。如果你是个的FreeBSD新手,你要认真考虑是否要运行它。

什么是FreeBSD-CURRENT?

FreeBSD-CURRENT从字面上理解就是FreeBSD的当前工作版。内容包括正在发展中,实验中,还有一些过渡时期的程序,这些程序都有可能被放进下一个正式发行版中。通常我们每天都会去编译FreeBSD-CURRENT的源代码,但是有时候程序还是有可能会出问题。通常这些问题都会尽快解决,但是有时候这些问题可能会带来麻烦,在新功能加入的24小时内也都有可能出问题。

谁需要FreeBSD-CURRENT?

FreeBSD-CURRENT的用户主要是下面三类人:

1.    正在源代码树的一些地方积极工作的FreeBSD组成员,对他们来说,保持“CURRENT”是绝对必要的。

2.    FreeBSD的测试组成员,他们花时间去检查各种问题,以确保FreeBSD-CURRENT能够尽可能地维持在最稳定的状态。同时这些测试人员也能够对FreeBSD的变革和未来的方向提出建议。

3.    FreeBSD组(或一些其他)的外部成员,他们只不过希望密切注意系统的变化,使用当前的源代码作参考(如阅读,而非运行)。这些人有时候也会提出建议或是贡献他们所写的代码。

What Is FreeBSD-CURRENT Not?

1.         快速得到预发行版程序,因为你听说有一些比较酷的新特性,你想成为第一个拥有它的人。

2.         得到错误修复的快捷方法。

3.         我们会负责提供官方支持。我们会尽力帮助那三类正当”FreeBSD-CURRENT用户,但是我们没时间为他们提供技术支持。我们这么做不是因为我们很吝啬,或是因为我们不想帮助大家(如果我们是这样的人,我们也不会为FreeBSD努力了),实在是因为我们无法每天回答400个问题,同时还要为FreeBSD而努力!我可以确定的一点就是,如果给各位选择到底是要回答绝大多数开发者和用户的问题还是改进FreeBSD,大多数人都会选择提高FreeBSD的能力。

使用FreeBSD-CURRENT

1.    加入FreeBSD-CURRENT邮件列表<freebsd-CURRENT@FreeBSD.org>FreeBSD CVS commit message 邮件列表<cvs-all@FreeBSD.org>这两个邮件列表。这不仅仅是一个好主意,它是精华。如果你没有加入FreeBSD-CURRENT邮件列表,你就无法知道其他人对现在的系统有什么意见,也可能因此在其他人早就发现的甚至已经解决了的问题面前陷入困境。更重要的是,你可能会错过一些能使你的系统保持稳定的重要公告。

FreeBSD CVS commit message 邮件列表<cvs-all@FreeBSD.org>则允许你看看每次修改所提交的日志记录,同时也会附上关于可能产生问题的相关信息。

如果你想要加入这些列表的话,只要写一封信给<majordomo@FreeBSD.org>,把下面这些放在你的信件正文:

subscribe freebsd-CURRENT

subscribe cvs-all

你也可以写上help,则Majordomo就会发送一篇关于如何订阅或取消订阅所有我们提供的邮件列表的完整说明给你。

2.    ftp.FreeBSD.ORG取得原始程序。你可以从下面三种方法中选一种来用。

a.         supfile文件()使用cvsup程序(附录A.6节介绍)。这是我们第二个推荐的方法,它可以让你只要一次就可以下载完整的collection,以后只要下载改变过的部分就可以了。很多人cron来运行cvsup,这样能够确保源代码会自动更新。如果你想使用这个方法,只要:

(注)(ftp://ftp.FreeBSD.org/pub/FreeBSD/FreeBSD-current/src/share/examples/cvsup/

standard-supfile

# pkg_add -f  ftp://ftp.FreeBSD.org/pub/FreeBSD/development/CVSup/cvsupit.tgz

b.         使用ftpFreeBSD-CURRENT的源代码树通常是通过 ftp://ftp.FreeBSD.ORG/pub/FreeBSD/FreeBSD-CURRENT来释出的。我们的FTP服务器也允许你以压缩或打包的形式抓取整个源代码树。例如你想下载:

usr.bin/lex

你可以执行下面的命令以tar文件的形式获得整个目录:

ftp> cd usr.bin

ftp> get lex.tar.Z

c.         使用CTM工具(附录A.5节介绍)。如果你网络连接状况很糟糕(连接成本太高或只可以用email访问),CTM是一个很好的选择。然而,可能会有很多连接错误而得到很多坏掉的文件。这导致它不能很好地工作,这又提高了长时间工作的机会。我们建议你用一个9600bpsmodem或更快的连接来使用CVSup

3.    如果你抓取源代码是为了运行而不仅仅是看的话,建议你把整个FreeBSD-CURRENT都下载回去,不要只下载一部分。这是因为这些程序互相都有关联性,如果你只想编译其中的部分程序的话,你一定会遇到困难。

在你编译FreeBSD-CURRENT之前,请先仔细阅读/usr/src下的Makefile 。你在升级的过程中,至少要第一时间执行make world(第19.4节)。阅读FreeBSD-CURRENT邮件列表<freebsd-CURRENT@FreeBSD.org>可以让你跟上其他方面发展的进程,有时当我们在进入下一个版本的时候,这就变得很有必要。

4.    大家活动起来!如果你正在使用FreeBSD-CURRENT,我们想知道你对它有什么意见,特别是你对增强性能或错误修正方面有些建议的话。如果你在建议时能附上相关程序代码的话那就更好了!

19.2.2使用FreeBSD的稳定版

什么是FreeBSD-STABLE

FreeBSD-STABLE是在推出下一个主版本之前我们的一个开发分支。它的变化并不大。实验性或是未测试过的功能并不会出现在这个分支上(请看FreeBSD-CURRENT)。这仍然是一个开发分支,这意味着在任何给定的时间,FreeBSD-STABLE的源代码可能或不可能适合任何特定的目的。它只是另一个工程开发版,不是针对最终用户。

谁需要FreeBSD-STABLE?

如果你对跟踪或贡献FreeBSD的开发进程感兴趣,特别是由于它与FreeBSD的下一发行版相关,那你应当考虑用FreeBSD-STABLE

如果只是对分支作一些安全修复的话,你不需要跟着FreeBSD-STABLE这样做。每一个安全方案都会解释如何修复它所影响的发行版的问题(注),仅仅为了安全原因就追踪整个开发分支可能会带来很多不必要的变化。

(注):那通常不是真的。虽然我们支持它们已经好多年了,但我们不可能永远继续支持旧版本的FreeBSD。一个旧FreeBSD版本的当前安全策略的完整描述请看www.FreeBSD.org/security

虽然我们努力确保FreeBSD-STABLE分支一直能够正确地编译和运行,但这不是绝对的保证。另外,当代码被加入FreeBSD-STABLE之前,它是在FreeBSD-CURRENT上开发的,更多的人是运行FreeBSD-STABLE而不是FreeBSD-CURRENT,所以,不可避免的,一些错误或问题可能会在FreeBSD-STABLE中发现,而不会出现在FreeBSD-CURRENT中。

由于这些原因,我们并不建议你盲目地追踪FreeBSD-STABLE,还有特别重要的是没有先在你的开发环境中彻底地测试代码,你不要升级任何生产服务器到FreeBSD-STABLE

如果你不知道如何做的话,我们建议你运行最新的FreeBSD发行版,然后使用二进制升级机制来从一个版本转移到另一个版本。

使用FreeBSD-STABLE

1.    加入FreeBSD-STABLE邮件列表<freebsd-STABLE@FreeBSD.org>。这个邮件列表会提供你有关STABLE的必要信息,或是其他特别需要注意的事项。当程序开发人员想要进行一些比较具有争议性的修改或升级时,他们也会在这个邮件列表里公告,给用户一个表达意见的机会。

FreeBSD CVS commit message邮件列表<cvs-all@FreeBSD.org>可以允许你看看针对每个修正提交的日志记录,其中包括了许多重要的信息。这也是一个值得订阅的邮件列表。

想要加入这些邮件列表的话,只要寄一封电子邮件到<majordomo@FreeBSD.org>,并在内容中注明:

subscribe freebsd-STABLE

subscribe cvs-all

你也可以写上help,则Majordomo就会发送一篇关于如何订阅或取消订阅所有我们提供的邮件列表的完整说明给你。

2.    如果你正在安装一个全新的系统,并且希望能够尽量地稳定,你可以从ftp://releng3.FreeBSD.org/pub/FreeBSD/取得最新分支的snapshot,安装的方法跟其他release的差不多。

如果你已经运行了FreeBSD的前一个版本,而且希望通过源代码来升级,你可以很容易地通过ftp.FreeBSD.org来完成。可以使用下面三种方法中的任一种:

a.     使用CTM工具(附录A.5)。除非你有一个好的速度十分稳定的TCP/IP网络连接,否则这就是你最好的选择。

b.    以这个supfie文件(注)使用cvsup(附录A.6)。这是我们第二推荐使用的方法,因为这个方法允许你一次性地抓取完整的源代码,然后再下载已经修改过的部分。很多人从cron运行cvsup来确保他们的源代码自动升级到最新版。有一个很简单的方法,你只要键入:

(注):(ftp://ftp.FreeBSD.org/pub/FreeBSD/FreeBSD-current/src/share/examples

/cvsup/stable-supfile

# pkg_add -f  ftp://ftp.FreeBSD.org/pub/FreeBSD/development/CVSup/cvsupit.tgz

d.    使用ftpFreeBSD-STABLE的源代码树可以在ftp://ftp.FreeBSD.ORG/pub/FreeBSD/FreeBSD-STABLE取得。

我们使用的是FTP服务器也允许你利用压缩或打包的方式把整个目录下载回去。例如你可以看到:

usr.bin/lex

你可以执行下面的命令以tar文件的形式得到整个目录:

ftp> cd usr.bin

ftp> get lex.tar.Z

3.    基本上,如果你需要快速按需要访问源代码,而且使用的网络带宽也不是问题的话,你可以使用cvsup或是ftp。要不然就使用CTM

4.    在你编译STABLE之前,先仔细阅读一下/usr/src下的Makefile。你在升级的过程中,至少要第一时间执行make world(第19.4节)。阅读FreeBSD-STABLE邮件列表 <freebsd-STABLE@FreeBSD.org>可以让你跟上其他方面发展的进程,有时当我们在进入下一个版本的时候,这就变得很有必要。

19.3同步你的源代码

有很多方法可以通过Internet连接(或是email)FreeBSD的源代码在给定的FreeBSD计划源代码范围或整个源代码范围内保持最新版本,之依赖于你对哪些部分感兴趣。我们提供的主要服务是Anonymous CVS(附录A.4),CVSup(附录A.6)和CTM(附录A.5)。

警告:当只升级你源代码树的某个部分时,唯一支持的升级进程是升级整个树然后重新编译用户级和内核级源代码(例如,所有的运行在用户水平的程序,如那些在/bin/sbin中的程序)。只升级你源代码树的一部分,仅仅升级内核级或仅仅用户级都将出现问题。这些问题可能是内核编译错误或是数据丢失。

Anonymous CVSCVSup是采用pull的方式来更新source的。以CVSup来说,当用户(或是cron)运行cvsup程序,它会和远程的cvsupd服务器取得联系,然后就会更新你的文件。你取回的更新文件是最新的,而且只有当你想要的时候,你才会拿到这些文件。你可以很轻易地限制你的更新动作,只更新你感兴趣的某个文件或某个目录。更新的动作是由服务端root根据你有什么以及你要什么来实时完成的。Anonymous CVS比起CVSup来说是简单很多了,它只是一个CVS的扩充版,允许你可以直接从远程的CVS仓库中取得修改过的部分。CVSup也可以做到这一点,而且更有效率,但是Anonymous CVS使用起来则容易得多。

另一方面,CTM并不是交互式地比较和对照你所拥有的源代码和服务器上的源代码或是你取得的更新部分。相反的,会有一个脚本文件专门用来辨别修改过的文件,这个程序是由主CTM服务器来执行,每天会比较几次,并把两次执行期间内修改过的文件加以压缩,给它们一个序号,然后就加以编码 (以可打印的ASCII字符为主) 并以email的方式寄出。当你收到它的时候,这些“CTM deltas”就可以由ctm.rmail这个程序来处理,它可以自动解码,确认并在用户的源代码上使用这些修改。这个程序比CVSup更有效率,而且这个动作对我们的服务器来说是比较轻松的,因为这是一个push的动作而不是pull的动作。

当然还有很多方法可以使用。如果你不小心把你的部分程序清除掉了,CVSup会扫描出来,并自动为你把不足的部分补齐。CTM并不会为你做这些动作,而Anonymous CVS则会觉得十分困惑。如果你清掉了你的部分源代码(而且你没有备份),你可以从头开始 (从最新的CVS“base delta”) 并用CTM来重建它们,或是用anoncvs来完成,只要把不正确的地方删掉再重新做同步的动作即可。

19.4使用make world来重建整个系统

一旦你同步了本地的某个FreeBSD版本的源代码树 (STABLECURRENT等等),你就必须利用这个源代码树重建整个系统。

作一个备份:在你做这事之前,我想不需要再强调做备份有多重要。做一个make world可能很简单,但当你出错时,你可能无法启动你的系统。请你确信一定要做备份。将一张修复软盘放在手边。你可能不一定会使用它,但有一张总比没有好!

预订正确的邮件列表:FreeBSD-STABLEFreeBSD-CURRENT分支都是开发中的版本。开发FreeBSD的都是人,不可能避免错误。有时,这些错误是无害的,只会让系统产生一些警告信息。而不是修改一些数据,让你的系统无法启动,或损坏你的文件(或者更糟)。如果真的发生这些问题,写上这些问题的标题,并发邮件到相应的邮件列表,解释问题的原因和它将影响哪些系统。当问题解决的时候,会发布一个“all clear”的声明。

如果你想追踪FreeBSD-STABLE FreeBSD-CURRENT,而无法读到FreeBSD-stable的邮件列表<freebsd-stable@FreeBSD.org>FreeBSD-current的邮件列表<freebsd-current@FreeBSD.org>,那你可能需要去问一下出了什么问题。

19.4.1读一下/usr/src/UPDATING

在你做其他事情之前,先读一下/usr/src/UPDATING。这个文件包含了很多你可能会遇到的很重要的信息,或指定了你运行某个命令的顺序。如果UPDATING与你在这儿读到的有些什么抵触,以UPDATING为准。

重要点:就像先前描述的,阅读UPDATING无法代替订阅正确的邮件列表。这两个的互相补充的,不是对立的。

19.4.2 检查/etc/make.conf

检查文件/etc/defaults/make.conf /etc/make.conf。第一个包含了一些默认的定义——它们中的绝大多数已被注释掉了。当你从源代码重建它们时,把它们添加到/etc/make.conf中。记住你添加的任何东西在你每次运行make时也会被用到,所以把它设置得适合你的系统是很明智的。

一个典型的用户将会把/etc/defaults/make.conf文件中的CFLAGS NOPROFILE行拷贝到/etc/make.conf文件中,然后不做注释。

检查其他的定义(COPTFLAGS, NOPORTDOCS等等),决定它们是否与你相关。

19.4.3 升级/etc/group

/etc目录包含了大部分的系统管理信息,就像你启动系统时运行的脚本一样。这些脚本随着FreeBSD的版本而改变。一些配置文件在一天天的系统运行中被使用。特别是,/etc/group

“make world”的安装部分已经确定了有默认用户名或组存在时,这正是时候。当执行一个升级时,看起来好像有三个组不存在。这会在升级时引起错误。

这里的绝大部分例子是当ppp组被添加的时候。当部分子系统安装时使用一个不存在的组名,用户会面对安装失败的可能。

解决方案是检查/usr/src/etc/group和比较你自己的组列表。如果在新文件中没有组,那可以把它们拷贝过去。同样地,你需要在/etc/group中重命名组,它有同样的GID,但在/usr/src/etc/group中是一个不同的名称。

提示:如果你是一个偏执狂,你可以检查你的系统看看哪个文件是将被你重命名或删除的组所拥有的。

    # find / -group GID -print

将显示所有被组GID所拥有的文件(它可能是一个组名,或是一个数字组ID)。

19.4.4转入单用户模式

你可能需要在单用户模式下编译系统。除了可以使编译速度明显加快之外,重新安装系统将触及到许多重要的系统文件,所有的标准系统程序,库,包括文件等。在运行系统时改变这些可能会引起问题(特别是你在系统中是active用户)。

另一种方法是在多用户模式下编译系统,然后进入单用户模式安装。如果你喜欢这样做,只要在下一步不拖延等到编译完成就可以了。

作为超级用户,你可以执行:

    # shutdown now

将会带你进入单用户模式。

另外一种方法是,重新启动系统,在启动命令行,键入-s选项。系统将启动进入单用户模式。在shell命令行你只要键入下面这些:

    # fsck -p

    # mount -u /

    # mount -a -t ufs

    # swapon -a

这个检查文件系统,重新挂上/ /写,通过参考/etc/fstab来挂上所有其他的UFS文件系统,然后把交换分区打开。

19.4.5 删除/usr/obj

作为系统重建的一部分,他们会在目录/usr/obj下被替换。目录被放在/usr/src下面。你可以加速make world的进程,然后通过删除这个目录来删除一些令你头痛的东西。一些在/usr/obj下的文件可能有一些需要先被删除的不可变的标记设置。

    # cd /usr/obj

    # chflags -R noschg *

    # rm -rf *

19.4.6重新编译源代码

保存输出

把通过运行make得到的输出文件保存到另一个文件是个好主意。如果发生什么错误,你需要有一个错误信息的副本。而这可能不会帮助你诊断发生了什么事情,如果你把你的问题提交到FreeBSD的一个邮件列表,它可以帮助其他人。

这样做的最容易办法是使用script命令,用一个参数来指定一个保存所有输出文件的名称。在重建world之前,你可以马上这样做,然后当处理完成后,键入exit

    # script /var/tmp/mw.out

    Script started output file is /var/tmp/mw.out  

    # make TARGET

    ... compilecompilecompile ...    

    # exit

    Script done...

如果你这样做,不要把输出保存在/tmp中。这个目录可能在你下次重新启动时会被清除。一个好的储存地方是在/var/tmp中,或在roothome目录。

编译和安装基础系统

你必须在/usr/src目录中

    # cd /usr/src

 (除非,你的源代码在其他地方,在这个例子中,将改在那个目录中)

要使用make world命令来重建系统。这个命令会从描述了如何编译FreeBSD来重建系统的Makefile文件中读取指令,并按这种规则来编译系统。

通常你键入的命令行格式是这样的:

    # make -x -DVARIABLE target

在这个例子中,-x是你给make的一个选项。看看make联机手册中的例子你就可以明白了。-DVARIABLE是一个传给Makefile文件的变量。Makefile的行为是受这些变量控制的。这些与你在/etc/make.conf中的设置变量是一样的,这儿提供了设置这些变量的另一种方法。

    # make -DNOPROFILE=true target

这是指定不需要被编译的库的另一种方法,是符合/etc/make.conf文件中的相关行的。

    NOPROFILE=true

    # Avoid compiling profiled libraries

target告诉make你要做什么。每个Makefile定义了许多不同的“target”,你选择的target决定了将发生什么。

一些target被列在Makefile文件中,但并不意味着你可以运行。而是,他们通过建立进程来把重建系统的必需步骤分解成许多小步骤。

大多数时间,你不需要键入任何参数,所以你可以键入下面的命令:

    # make target

FreeBSD2.2.5版本开始,world target被分解成两部分,buildworldinstallworld。正如它的名字所表达的,buildworld完全在/usr/obj下编译了一个完全新的树,installworld把这棵树安装在当前机器上。

这非常有用,主要有2个原因。

第一,它允许你安全地编译安装,而不影响你系统的任何组件。而且编译安装是自主机型的(selfhosted)。因为这个原因,你可以在一台机器上以多用户模式安全地运行buildworld。但仍然建议你在单用户模式下运行installworld

第二,它允许你在网络上使用NFS来升级多台机器。如果你有三台机器,你想升级A B C,运行make buildworld,然后在Amake installworldBCA上用NFS挂上/usr/src/usr/obj,你就可以运行make installworld来进行升级BC

虽然,world target仍然存在,但还是不鼓励你使用它,运行:

    # make buildworld

现在可以通过指定一个-j选项来编译,它可以产生多个并发进程的处理。这在多处理器的机器上是很重要的。然而,既然绝大多数的编译处理是IO处理多于CPU处理,它在单CPU机器上也是有用的。

在一个典型的单CPU机器上,你可以运行:

    # make -j4 buildworld

如果你有一个多处理器的机器,你可以使用一个SMP的配置内核,可以试试610,看看它们的速度怎么样。

定时

许多因素会影响到编译时间,但现在一台500 MHzPentium 3机器,带有128 MB内存,大概需要使用3个半小时的时间来编译FreeBSD-CURRENT的树,在处理时是没有任何窍门或捷径的。一个FreeBSD-STABLE树将编译得快一些。

19.4.7编译和安装一个新的内核

要充分发挥你的新系统的性能,你需要重新编译内核。这是必须的,就像某个内存结构发生了变化,像pstop这样的程序就不能工作,除非内核和源代码的版本是一致的。最简单,安全的方法是以GENERIC为基础来编译和安装一个内核。当GENERIC不能很好地支持你系统的所有设备时,就需要回到单用户模式。这是一个很好的检测系统的方法。从GENERIC启动以后,修改你的系统,你可以在你普通内核配置文件的基础上编译一个新的内核。

如果你升级到FreeBSD 4.0或更高版本,不赞成使用标准内核编译程序(在第9章描述)。而是,你应当运行这些命令:

    # cd /usr/src

    # make buildkernel

    # make installkernel

如果你升级到低于FreeBSD 4.0的版本,你可以使用标准的内核编译程序。然而,建议你使用新的config,使用下面的命令行。

    # /usr/obj/usr/src/usr.sbin/config/config KERNELNAME

19.4.8重新启动进入单用户模式

你应当重新启动进入单用户模式来测试新的内核。你只需要执行第19.4.4节的命令。

19.4.9安装新的系统程序

如果你正在编译一个新版本的FreeBSD,而且已经使用make buildworld,那么你现在可以使用installworld来安装新的系统程序。

运行:

    # make installworld

注意:如果你在make buildworld命令行指定了变量,你必须在make installworld命令行也指定同样的变量。这里不需要指定其他的选项。

例如,如果你运行:

    # make -DNOPROFILE=true buildworld

你必须安装:

           # make -DNOPROFILE=true installworld

否则,它将设法安装在make buildworld过程中没有建立的配置库。

19.4.10通过make world来升级文件

重新make world将不会用新的或修改过的配置文件来升级某个目录(特别是/etc/var /usr)。

升级这些文件的最简单的方法是使用mergemaster命令,如果你想这样做的话,你必须要手工操作。我们强烈建议你使用mergemaster。然而,如果你已经这样做,那你可以跳过这个直接进入下一节。你可以先看看它的联机手册,然后在/etc下编译一个备份以避免出错。

如果你想手工升级,你不需要把所有文件从/usr/src/etc拷到/etc。这些文件中的某些必须先被安装。这是因为/usr/src/etc目录不是你所看到的目录/etc的一个拷贝。另外,这些文件是在/etc下,而不是在/usr/src/etc下。

最简单的方法是把这些文件手工安装到一个新的目录,然后进行修改。

备份你的目录/etc把你的目录备份起来,会比较安全一些。可以这样:

    # cp -Rp /etc /etc.old

-R执行一个递归拷贝,-P保存时钟,文件的所有者以及诸如此类的。

你必须建立一个虚拟的目录来安装新的/etc和其他文件。/var/tmp/root是一个选择,在这个下面有许多子目录。

    # mkdir /var/tmp/root

    # cd /usr/src/etc

    # make DESTDIR=/var/tmp/root distrib-dirs distribution

这将建立必须的目录结构和安装文件。许多创建在/var/tmp/root下的子目录是空的,将被删除。最简单的方法是这样:

    # cd /var/tmp/root

    # find -d . -type d | xargs rmdir 2>/dev/null

这将删除所有空目录。现在/var/tmp/root包含了所有将被放在/下面的文件。你现在必须仔细检查每个文件,查出与你已存在的文件有什么不同。

注意有些文件将会被安装在/var/tmp/root下并且带上一个'.'。在写入时,只有这样的文件才会在/var/tmp/root//var/tmp/root/root/中被启动。确定你使用了ls -a 来列出它们。

这样做的最简单方法是使用diff来比较两个文件。

    # diff /etc/shells /var/tmp/root/etc/shells

这将显示你的/etc/shells文件和新的/etc/shells文件之间的不同。

用一个时钟标记来命名新的根目录(/var/tmp/root),所以你可以很容易地比较版本之间的不同:通常重建系统意味着你必须升级/etc,这是很烦琐的。

你可以保存一个你合并到目录中的最后设置的修改文件的拷贝来加快这个处理。下面的程序将给出一个好主意。

1.    像通常一样Make world。当你要升级/etc和其他目录时,给出一个以当前日期命名的target目录。如果你在14th February 1998做,你就可以这样:

# mkdir /var/tmp/root-19980214

# cd /usr/src/etc

# make DESTDIR=/var/tmp/root-19980214 \

distrib-dirs distribution

2.    从这个目录中合并入修改的部分。

完成时,不要删除目录/var/tmp/root-19980214

3.    当你已经下载了最新版本的源代码并且重建之后,接着第1步。这将产生一个新目录叫做:/var/tmp/root-19980221。如果你作修改时等了一个月)

4.    你可以使用diff来看看与一周前相比发生了哪些变化。

# cd /var/tmp

# diff -r root-19980214 root-19980221

典型的,这将在/var/tmp/root-19980221/etc/etc之间有一些小小的变化。因为变化比较小,所以可以很容易地把这些修改存入/etc目录。

5.    你现在可以删除两个/var/tmp/root-*目录中比较旧的那个了。

# rm -rf /var/tmp/root-19980214

6.    每次你需要合并这些修改到/etc中,只要重复执行这个操作。你可以使用date来自动产生目录的名称。

# mkdir /var/tmp/root-`date “+%Y%m%d”`

19.4.11 升级/dev

DEVFS: 如果你正在使用DEVFS,这是不需要的。

在绝大多数情况下,mergemaster工具将认识到,当它必须要升级设备时,可以自动地完成它。这些指示将告诉你如何手动地升级设备。

出于安全考虑,这是一个多步的处理过程。

1.    拷贝/var/tmp/root/dev/MAKEDEV /dev

# cp /var/tmp/root/dev/MAKEDEV /dev

如果你使用mergemaster来升级/etc,那你的MAKEDEV脚本也必须被升级,如果有必要,你可以手动拷贝它。

2.    现在,对你当前的/dev作一个大概的快照(snapshot)。这个快照需要保存权限,所有者,每个文件名的主次号码,但它不包括时钟标记。这样做的最简单方法是使用awk来显示它们的一些信息。

# cd /dev

# ls -l | awk '{print $1 $2 $3 $4 $5 $6 $NF}' > /var/tmp/dev.out

3.    重新编译所有的设备。

# sh MAKEDEV all

4.    写入另一个目录的快照,这是会输出到/var/tmp/dev2.out。现在,检查这两个文件中你没有创建的设备。一概不会有很多,但这样总归比较安全。,

# diff /var/tmp/dev.out /var/tmp/dev2.out

你可以使用下面的命令来注意磁盘分区的差异

# sh MAKEDEV sd0s1

要重新创建slice记录。你的精确的系统环境需要作修改。

19.4.12 升级/stand

注意:这步只是作为完全操作的选择。它可以被略过。

你可能需要升级/stand目录下的文件。这些文件包含了许多与/stand/sysinstall程序的硬连接。这个程序是被静止连接的,所以当没有其他文件系统被挂上时,它仍能工作。

    # cd /usr/src/release/sysinstall

    # make all install

19.4.13重新启动

你现在已经完成了。你检验完右边出现的信息时,你可以重新启动系统了。一个简单的fastboot是这样的。

    # fastboot

19.4.14 完成

你已经成功升级了你的FreeBSD系统。祝贺你。

如果发生些错误,重新建立系统是很容易的。例如,如果你意外地删除了作为升级系统一部分的/etc/magicfile命令将停止工作。在这种情况下,可以这样来修复:

    # cd /usr/src/usr.bin/file

    # make all install

19.4.15 问题解答

1.每次变化的时候,我都需要重新编译系统吗?

这个问题不太容易回答,因为它依赖于实际发生了多大的变化。例如,如果你只运行CVSup,而且下面这些文件也被升级了,

src/games/cribbage/instr.c

src/games/sail/pl_main.c

src/release/sysinstall/config.c

src/release/sysinstall/media.c

src/share/mk/bsd.port.mk

那就不需要重新编译整个系统。你只需要到相应的子目录,然后make all install,就这么简单。但如果发生了比较大的变化,例如/src/lib/libc/stdlib,那你必须重新编译整个系统,或者至少它的那些组件需要被重新静态连接一下。

一天下来,你可能会兴奋地大叫。你可以每隔两个星期重新编译一次系统,不断地跟上最新的修正。或者,你可能想重新编译那些修改过的东西,你必须很自信地知道你可以区分出所有相互之间的依赖关系。

当然,这都依赖于你是如何经常升级的,你是否正在跟踪FreeBSD-STABLE FreeBSD-CURRENT

2. 我的编译失败了,而且带有很多signal 11(或其他signal)的错误提示。发生了什么?

这通常是硬件出问题了。(重新)编译系统是强迫测试你的硬件的很有效的方法,同时也会频繁地产生内存问题。这些通常表明在收到奇怪的signal后会产生编译器错误。

这明确地指出了如果你重新编译,它还是会在进程的某个点上死掉。

在这个例子中,除了在你机器的组件之间启动交换来决定是哪一个坏了,你别无他法。

3. 当我完成的时候,我可以删除/usr/obj吗?

最简短的回答是yes/usr/obj包含所有的在编译过程中产生的目标文件。通常,在编译整个系统的第一步是删除这个目录,然后重新启动。在这个例子中,你完全理解之后,可以删除/usr/obj,然后将释放很多的磁盘空间(大概是340MB)。

然而,如果你知道在“make world”时可以跳过这步。这将在编译时运行得更快,因为绝大多数源代码不一定要重新编译。有一个不是很重要的问题是可能会混进一些依赖性的问题,导致你用旧的方法编译时会出错。这通常会在FreeBSD邮件列表中产生争论,当有人说他们建立失败时,就是不明白是因为他们抄近路造成的。

如果你想经历了危险,接着make world,通过定义NOCLEANmake,像这样:

# make -DNOCLEAN world

4.         被打断的编译能恢复吗?

这依赖于你发现问题之前,进程已经执行到什么样的程度。通常,“make world”进程会建立新的基本工具的拷贝(如gccmake)和系统库。这些工具和库接着将被安装。新的工具和库也会被重新建立和重新安装。整个系统(现在包括普通的用户程序,如lsgrep)就用新的系统文件重新建立。

如果你在最后一个步骤,你很清楚(因为你已经检查过了你存储的输出),那你可以这样做:

……fix the problem……

# cd /usr/src

# make -DNOCLEAN all

这将不会取消先前的“make world”工作。如果你在“make world”的输出中,看到这样的信息,

--------------------------------------------------------------

Building everything..

--------------------------------------------------------------

那大概可以安全地这样做。

如果你没有看到这样的信息,或你不能确定,那最好重新启动建立程序。

5.         我可以使用一台作为master的机器来升级许多机器吗(NFS?

这是很简单的任务,可以为很多机器节约好几个小时的编译时间。只要在一台中央机器上运行buildworld,然后在远程机器和installworld上,用NFS /usr/src/usr/obj挂上。

6.         我如何可以加快编译速度呢?

             运行在单用户模式下。

             /usr/src/usr/obj目录放在连接多个磁盘的分离文件系统上。如果可能的话,把这些磁盘防在分离的磁盘控制器上。

             更好的是,使用ccd设备用这些文件系统连接多个磁盘。

             关闭配置(在/etc/make.conf中设置“NOPROFILE=true”)。你几乎不需要做什么。

             也是在/etc/make.conf中,设置CFLAGS成这样“-O -pipe”。最优化选项“-O2”会更慢,在“-O” “-O2”之间的性能差异通常是不用考虑的。“-pipe”让编译器使用管道,而不是用于通信的临时文件,这可以节省磁盘的访问(会增加内存的使用量)。

             编译时加上-j<n>选项,以便并行地运行多个进程。这通常对一个单处理器或多处理器的机器都是有帮助的。

             包含的/usr/src文件系统可以加上noatime选项来被挂上(或卸下)。这阻止了文件系统记录文件访问时间。你大概不需要这个信息。

# mount -u -o noatime /usr/src

警告:这个例子假设/usr/src是在你自己的文件系统上。如果它不是(如果它是这个例子中/usr的一部分),那你将必须使用文件系统的加载点,而不是/usr/src

             包含/usr/obj的文件系统可以用“async”选项来被挂上(或卸下)。这可以让磁盘进行异步操作。另外,写入一完成,数据就会在几秒钟以后被写入到磁盘。这允许按丛的方式来写入操作,会提供更好的性能。

警告:记住这个选项会让你的文件系统更加脆弱。加上这个选项可能会增加电源发生故障的机会,当机器重新启动时,文件系统将处于无法恢复的状态。

如果/usr/obj在这个文件系统上是唯一的东西,那它就不是问题。如果你有其他的,在同一个文件系统上有价值的数据,那在启用这个选项前先做好备份。

# mount -u -o async /usr/obj

警告:正如上面所说的,如果/usr/obj不在它自己的文件系统上,在这个例子中用         相应的加载点名称来替换它。