<?xml version="1.0" encoding="iso-8859-1"?>
<!--
     The FreeBSD Documentation Project

     $FreeBSD$
-->

<chapter id="updating-upgrading">
  <chapterinfo>
    <authorgroup>
      <author>
	<firstname>Jim</firstname>
	<surname>Mock</surname>
	<contrib>Restructured, reorganized, and parts updated
	  by </contrib>
      </author>
      <!-- Mar 2000 -->
    </authorgroup>

    <authorgroup>
      <author>
	<firstname>Jordan</firstname>
	<surname>Hubbard</surname>
	<contrib>Original work by </contrib>
      </author>

      <author>
	<firstname>Poul-Henning</firstname>
	<surname>Kamp</surname>
      </author>

      <author>
	<firstname>John</firstname>
	<surname>Polstra</surname>
      </author>

      <author>
	<firstname>Nik</firstname>
	<surname>Clayton</surname>
      </author>
    </authorgroup>
    <!-- with feedback from various others -->
  </chapterinfo>

  <title>Updating and Upgrading &os;</title>

  <sect1 id="updating-upgrading-synopsis">
    <title>Synopsis</title>

    <para>&os; is under constant development between releases.  Some
      people prefer to use the officially released versions, while
      others prefer to keep in sync with the latest developments.
      However, even official releases are often updated with security
      and other critical fixes.  Regardless of the version used, &os;
      provides all necessary tools to keep your system updated, and
      also allows for easy upgrades between versions.  This chapter
      will help you decide if you want to track the development
      system, or stick with one of the released versions.  The basic
      tools for keeping your system up to date are also
      presented.</para>

    <para>After reading this chapter, you will know:</para>

    <itemizedlist>
      <listitem>
	<para>What utilities may be used to update the system and
	  the Ports Collection.</para>
      </listitem>

      <listitem>
	<para>How to keep your system up to date with
	  <application>freebsd-update</application>,
	  <application>Subversion</application>, or
	  <application>CTM</application>.</para>
      </listitem>

      <listitem>
	<para>How to compare the state of an installed system against
	  a known pristine copy.</para>
      </listitem>

      <listitem>
	<para>How to keep your documentation up to date with
	  <application>Subversion</application> or documentation
	  ports<!--, and <application>Docsnap</application>-->.</para>
      </listitem>

      <listitem>
	<para>The difference between the two development
	  branches: &os.stable; and &os.current;.</para>
      </listitem>

      <listitem>
	<para>How to rebuild and reinstall the entire base
	  system with <command>make buildworld</command> (etc).</para>
      </listitem>
    </itemizedlist>

    <para>Before reading this chapter, you should:</para>

    <itemizedlist>
      <listitem>
	<para>Properly set up your network connection (<xref
	    linkend="advanced-networking"/>).</para>
      </listitem>

      <listitem>
	<para>Know how to install additional third-party
	  software (<xref linkend="ports"/>).</para>
      </listitem>
    </itemizedlist>

    <note>
      <para>Throughout this chapter, the <command>svn</command>
	command is used to obtain and update &os; sources.  To use it,
	you will need to install the port or the package for <filename
	  role="package">devel/subversion</filename>.</para>
    </note>
  </sect1>

  <sect1 id="updating-upgrading-freebsdupdate">
    <sect1info>
      <authorgroup>
	<author>
	  <firstname>Tom</firstname>
	  <surname>Rhodes</surname>
	  <contrib>Written by </contrib>
	</author>
      </authorgroup>
      <authorgroup>
	<author>
	  <firstname>Colin</firstname>
	  <surname>Percival</surname>
	  <contrib>Based on notes provided by </contrib>
	</author>
      </authorgroup>
    </sect1info>
    <title>FreeBSD Update</title>

    <indexterm><primary>Updating and Upgrading</primary></indexterm>
    <indexterm>
      <primary>freebsd-update</primary>
      <see>updating-upgrading</see>
    </indexterm>

    <para>Applying security patches is an important part of
      maintaining computer software, especially the operating system.
      For the longest time on &os; this process was not an easy one.
      Patches had to be applied to the source code, the code rebuilt
      into binaries, and then the binaries had to be
      re-installed.</para>

    <para>This is no longer the case as &os; now includes a utility
      simply called <command>freebsd-update</command>.  This utility
      provides two separate functions.  First, it allows for binary
      security and errata updates to be applied to the &os; base
      system without the build and install requirements.  Second, the
      utility supports minor and major release upgrades.</para>

    <note>
      <para>Binary updates are available for all architectures and
	releases currently supported by the security team.
	Before updating to a new release, the current
	release announcements should be reviewed as they may contain
	important information pertinent to the desired release.  These
	announcements may be viewed at the following link:
	<ulink url="http://www.FreeBSD.org/releases/"></ulink>.</para>
    </note>

    <para>If a <command>crontab</command> utilizing the features
      of &man.freebsd-update.8; exists, it must be
      disabled before the following operation is started.</para>

    <sect2 id="freebsdupdate-config-file">
      <title>The Configuration File</title>

      <para>Some users may wish to tweak the default configuration
	file in <filename>/etc/freebsd-update.conf</filename>,
	allowing better control of the process.  The options are very
	well documented, but the following few may require a bit more
	explanation:</para>

      <programlisting># Components of the base system which should be kept updated.
Components src world kernel</programlisting>

      <para>This parameter controls what parts of &os; will be kept up
	to date.  The default is to update the source code, the entire
	base system, and the kernel.  Components are the same as those
	available during the install, for instance, adding
	<literal>world/games</literal> here would allow game patches
	to be applied.  Using <literal>src/bin</literal> would allow
	the source code in
	<filename class="directory">src/bin</filename> to be
	updated.</para>

      <para>The best option is to leave this at the default as
	changing it to include specific items will require the user
	to list every item they prefer to be updated.  This could
	have disastrous consequences as source code and binaries may
	become out of sync.</para>

      <programlisting># Paths which start with anything matching an entry in an IgnorePaths
# statement will be ignored.
IgnorePaths</programlisting>

      <para>Add paths, such as
	<filename class="directory">/bin</filename> or
	<filename class="directory">/sbin</filename> to leave these
	specific directories untouched during the update
	process.  This option may be used to prevent
	<command>freebsd-update</command> from overwriting local
	modifications.</para>

      <programlisting># Paths which start with anything matching an entry in an UpdateIfUnmodified
# statement will only be updated if the contents of the file have not been
# modified by the user (unless changes are merged; see below).
UpdateIfUnmodified /etc/ /var/ /root/ /.cshrc /.profile</programlisting>

      <para>Update configuration files in the specified directories
	only if they have not been modified.  Any changes made by the
	user will invalidate the automatic updating of these files.
	There is another option,
	<literal>KeepModifiedMetadata</literal>, which will instruct
	<command>freebsd-update</command> to save the changes during
	the merge.</para>

      <programlisting># When upgrading to a new &os; release, files which match MergeChanges
# will have any local changes merged into the version from the new release.
MergeChanges /etc/ /var/named/etc/</programlisting>

      <para>List of directories with configuration files that
	<command>freebsd-update</command> should attempt merges in.
	The file merge process is a series of &man.diff.1; patches
	similar to &man.mergemaster.8; with fewer options, the merges
	are either accepted, open an editor, or
	<command>freebsd-update</command> will abort.  When in doubt,
	backup <filename class="directory">/etc</filename> and just
	accept the merges.  See <xref linkend="mergemaster"/> for more
	information about the <command>mergemaster</command>
	command.</para>

      <programlisting># Directory in which to store downloaded updates and temporary
# files used by &os; Update.
# WorkDir /var/db/freebsd-update</programlisting>

      <para>This directory is where all patches and temporary
	files will be placed.  In cases where the user is doing
	a version upgrade, this location should have a least a
	gigabyte of disk space available.</para>

      <programlisting># When upgrading between releases, should the list of Components be
# read strictly (StrictComponents yes) or merely as a list of components
# which *might* be installed of which &os; Update should figure out
# which actually are installed and upgrade those (StrictComponents no)?
# StrictComponents no</programlisting>

      <para>When set to <literal>yes</literal>,
	<command>freebsd-update</command> will assume that the
	<literal>Components</literal> list is complete and will not
	attempt to make changes outside of the list.  Effectively,
	<command>freebsd-update</command> will attempt to update
	every file which belongs to the <literal>Components</literal>
	list.</para>
    </sect2>

    <sect2 id="freebsdupdate-security-patches">
      <title>Security Patches</title>

      <para>Security patches are stored on a remote machine and
	may be downloaded and installed using the following
	command:</para>

      <screen>&prompt.root; <userinput>freebsd-update fetch</userinput>
&prompt.root; <userinput>freebsd-update install</userinput></screen>

      <para>If any kernel patches have been applied the system will
	need a reboot.  If all went well the system should be patched
	and <command>freebsd-update</command> may be run as a nightly
	&man.cron.8; job.  An entry in
	<filename>/etc/crontab</filename> would be sufficient to
	accomplish this task:</para>

      <programlisting>@daily                                  root    freebsd-update cron</programlisting>

      <para>This entry states that once every day, the
	<command>freebsd-update</command> utility will be run.  In
	this way, using the <option>cron</option> argument,
	<command>freebsd-update</command> will only check if updates
	exist.  If patches exist, they will automatically be
	downloaded to the local disk but not applied.  The
	<username>root</username> user will be sent an email so they
	may install them manually.</para>

      <para>If anything went wrong, <command>freebsd-update</command>
	has the ability to roll back the last set of changes with
	the following command:</para>

      <screen>&prompt.root; <userinput>freebsd-update rollback</userinput></screen>

      <para>Once complete, the system should be restarted if the
	kernel or any kernel modules were modified.  This will allow
	&os; to load the new binaries into memory.</para>

      <para>The <command>freebsd-update</command> utility can
	automatically update the <filename>GENERIC</filename> kernel
	only.  If a custom kernel is in use, it will have to be
	rebuilt and reinstalled after
	<command>freebsd-update</command> finishes installing the rest
	of the updates.  However, <command>freebsd-update</command>
	will detect and update the <filename>GENERIC</filename> kernel
	in
	<filename class="directory">/boot/GENERIC</filename> (if it
	exists), even if it is not the current (running) kernel of the
	system.</para>

      <note>
	<para>It is a good idea to always keep a copy of the
	  <filename>GENERIC</filename> kernel in
	  <filename class="directory">/boot/GENERIC</filename>.  It
	  will be helpful in diagnosing a variety of problems, and in
	  performing version upgrades using
	  <command>freebsd-update</command> as described in
	  <xref linkend="freebsdupdate-upgrade"/>.</para>
      </note>

      <para>Unless the default configuration in
	<filename>/etc/freebsd-update.conf</filename> has been
	changed, <command>freebsd-update</command> will install the
	updated kernel sources along with the rest of the updates.
	Rebuilding and reinstalling your new custom kernel can then be
	performed in the usual way.</para>

      <note>
	<para>The updates distributed via
	  <command>freebsd-update</command>, do not always involve the
	  kernel.  It will not be necessary to rebuild your custom
	  kernel if the kernel sources have not been modified by the
	  execution of <command>freebsd-update install</command>.
	  However, <command>freebsd-update</command> will always
	  update the <filename>/usr/src/sys/conf/newvers.sh</filename>
	  file.  The current patch level (as indicated by the
	  <literal>-p</literal> number reported by
	  <command>uname -r</command>) is obtained from this file.
	  Rebuilding your custom kernel, even if nothing else changed,
	  will allow &man.uname.1; to accurately report the current
	  patch level of the system.  This is particularly helpful
	  when maintaining multiple systems, as it allows for a quick
	  assessment of the updates installed in each one.</para>
      </note>
    </sect2>

    <sect2 id="freebsdupdate-upgrade">
      <title>Major and Minor Version Upgrades</title>

      <para>Upgrades from one minor version of &os; to another, like
	from &os;&nbsp;9.0 to &os;&nbsp;9.1, are called
	<emphasis>minor version</emphasis> upgrades.  Generally,
	installed applications will continue to work without problems
	after minor version upgrades.</para>

      <para><emphasis>Major version</emphasis> upgrades are when &os;
	is upgraded from one major version to another, like from
	&os;&nbsp;8.X to &os;&nbsp;9.X.  Major version upgrades will
	remove old object files and libraries which will break most
	third party applications.  It is recommended that all
	installed ports either be removed and re-installed or upgraded
	after a major version upgrade by using the
	<filename role="package">ports-mgmt/portupgrade</filename>
	utility.  A brute-force rebuild of all installed
	applications can be accomplished with this command:</para>

      <screen>&prompt.root; <userinput>portupgrade -af</userinput></screen>

      <para>This will ensure everything will be re-installed
	correctly.  Note that setting the
	<makevar>BATCH</makevar> environment variable to
	<literal>yes</literal> will answer <literal>yes</literal> to
	any prompts during this process, removing the need for
	manual intervention during the build process.</para>

      <sect3 id="freebsd-update-custom-kernel">
	<title>Dealing with Custom Kernels</title>

	<para>If a custom kernel is in use, the upgrade process is
	  slightly more involved, and the procedure varies depending
	  on the version of &os;.</para>

	<sect4 id="freebsd-update-custom-kernel-8x">
	  <title>Custom Kernels with &os;&nbsp;8.X and Earlier</title>

	  <para>A copy of the
	    <filename>GENERIC</filename> kernel is needed, and it
	    should be placed in <filename
	      class="directory">/boot/GENERIC</filename>.  If the
	    <filename>GENERIC</filename> kernel is not already present
	    in the system, it may be obtained using one of the
	    following methods:</para>

	  <itemizedlist>
	    <listitem>
	      <para>If a custom kernel has only been built once, the
		kernel in <filename
		  class="directory">/boot/kernel.old</filename> is
		actually the <filename>GENERIC</filename> one.  Simply
		rename this directory to <filename
		  class="directory">/boot/GENERIC</filename>.</para>
	    </listitem>

	    <listitem>
	      <para>Assuming physical access to the machine is
		possible, a copy of the <filename>GENERIC</filename>
		kernel can be installed from the CD-ROM media.  Insert
		your installation disc and use the following
		commands:</para>

	      <screen>&prompt.root; <userinput>mount /cdrom</userinput>
&prompt.root; <userinput>cd /cdrom/<replaceable>X.Y-RELEASE</replaceable>/kernels</userinput>
&prompt.root; <userinput>./install.sh GENERIC</userinput></screen>

	      <para>Replace <filename
		  class="directory"><replaceable>X.Y-RELEASE</replaceable></filename>
		with the actual version of the release you are using.
		The <filename>GENERIC</filename> kernel will be
		installed in <filename
		  class="directory">/boot/GENERIC</filename> by
		default.</para>
	    </listitem>

	    <listitem>
	      <para>Failing all the above, the
		<filename>GENERIC</filename> kernel may be rebuilt and
		installed from the sources:</para>

	      <screen>&prompt.root; <userinput>cd /usr/src</userinput>
&prompt.root; <userinput>env DESTDIR=/boot/GENERIC make kernel __MAKE_CONF=/dev/null SRCCONF=/dev/null</userinput>
&prompt.root; <userinput>mv /boot/GENERIC/boot/kernel/* /boot/GENERIC</userinput>
&prompt.root; <userinput>rm -rf /boot/GENERIC/boot</userinput></screen>

	      <para>For this kernel to be picked up as
		<filename>GENERIC</filename>
		by <command>freebsd-update</command>, the
		<filename>GENERIC</filename> configuration file must
		not have been modified in any way.  It is also
		suggested that it is built without any other special
		options.</para>
	    </listitem>
	  </itemizedlist>

	  <para>Rebooting to the <filename>GENERIC</filename> kernel
	    is not required at this stage.</para>
	</sect4>

	<sect4 id="freebsd-update-custom-kernel-9x">
	  <title>Custom Kernels with &os;&nbsp;9.X and Later</title>

	  <itemizedlist>
	    <listitem>
	      <para>If a custom kernel has only been built once, the
		kernel in
		<filename
		  class="directory">/boot/kernel.old</filename>
		is actually the <literal>GENERIC</literal> kernel.
		Rename this directory to <filename
		  class="directory">/boot/kernel</filename>.</para>
	    </listitem>

	    <listitem>
	      <para>If physical access to the machine is available, a
		copy of the <literal>GENERIC</literal> kernel can be
		installed from the CD-ROM media.  Load the
		installation disc and use these commands:</para>

	      <screen>&prompt.root; <userinput>mount /cdrom</userinput>
&prompt.root; <userinput>cd /cdrom/usr/freebsd-dist</userinput>
&prompt.root; <userinput>tar -C/ -xvf kernel.txz boot/kernel/kernel</userinput></screen>
	    </listitem>

	    <listitem>
	      <para>If the options above cannot be used, the
		<literal>GENERIC</literal> kernel may be rebuilt and
		installed from the sources:</para>

	      <screen>&prompt.root; <userinput>cd /usr/src</userinput>
&prompt.root; <userinput>make kernel __MAKE_CONF=/dev/null SRCCONF=/dev/null</userinput></screen>

	      <para>For this kernel to be identified as the
		<literal>GENERIC</literal> kernel by
		<command>freebsd-update</command>, the
		<filename>GENERIC</filename> configuration file must
		not have been modified in any way.  It is also
		suggested that the kernel is built without any other
		special options.</para>
	    </listitem>
	  </itemizedlist>

	  <para>Rebooting to the <filename>GENERIC</filename> kernel
	    is not required at this stage.</para>
	</sect4>
      </sect3>

      <sect3 id="freebsdupdate-using">
	<title>Performing the Upgrade</title>

	<para>Major and minor version upgrades may be performed by
	  providing <command>freebsd-update</command> with a release
	  version target, for example, the following command will
	  update to &os;&nbsp;8.1:</para>

	<screen>&prompt.root; <userinput>freebsd-update -r 8.1-RELEASE upgrade</userinput></screen>

	<para>After the command has been received,
	  <command>freebsd-update</command> will evaluate the
	  configuration file and current system in an attempt to
	  gather the information necessary to update the system.  A
	  screen listing will display what components have been
	  detected and what components have not been detected.  For
	  example:</para>

	<screen>Looking up update.FreeBSD.org mirrors... 1 mirrors found.
Fetching metadata signature for 8.0-RELEASE from update1.FreeBSD.org... done.
Fetching metadata index... done.
Inspecting system... done.

The following components of FreeBSD seem to be installed:
kernel/smp src/base src/bin src/contrib src/crypto src/etc src/games
src/gnu src/include src/krb5 src/lib src/libexec src/release src/rescue
src/sbin src/secure src/share src/sys src/tools src/ubin src/usbin
world/base world/info world/lib32 world/manpages

The following components of FreeBSD do not seem to be installed:
kernel/generic world/catpages world/dict world/doc world/games
world/proflibs

Does this look reasonable (y/n)? y</screen>

	<para>At this point, <command>freebsd-update</command> will
	  attempt to download all files required for the upgrade.  In
	  some cases, the user may be prompted with questions
	  regarding what to install or how to proceed.</para>

	<para>When using a custom kernel, the above step will produce
	  a warning similar to the following:</para>

	<screen>WARNING: This system is running a "<replaceable>MYKERNEL</replaceable>" kernel, which is not a
kernel configuration distributed as part of FreeBSD 8.0-RELEASE.
This kernel will not be updated: you MUST update the kernel manually
before running "/usr/sbin/freebsd-update install"</screen>

	<para>This warning may be safely ignored at this point.  The
	  updated <filename>GENERIC</filename> kernel will be used as
	  an intermediate step in the upgrade process.</para>

	<para>After all patches have been downloaded to the local
	  system, they will then be applied.  This process may take a
	  while depending on the speed and workload of the machine.
	  Configuration files will then be merged&nbsp;&mdash; this
	  part of the process requires some user intervention as a
	  file may be merged or an editor may appear on screen for a
	  manual merge.  The results of every successful merge will be
	  shown to the user as the process continues.  A failed or
	  ignored merge will cause the process to abort.  Users may
	  wish to make a backup of <filename
	    class="directory">/etc</filename> and manually merge
	  important files, such as
	  <filename>master.passwd</filename> or
	  <filename>group</filename> at a later time.</para>

	<note>
	  <para>The system is not being altered yet, all patching and
	    merging is happening in another directory.  When all
	    patches have been applied successfully, all configuration
	    files have been merged and it seems the process will go
	    smoothly, the changes will need to be committed by the
	    user.</para>
	</note>

	<para>Once this process is complete, the upgrade may be
	  committed to disk using the following command.</para>

	<screen>&prompt.root; <userinput>freebsd-update install</userinput></screen>

	<para>The kernel and kernel modules will be patched first.  At
	  this point the machine must be rebooted.  If the system was
	  running with a custom kernel, use the &man.nextboot.8;
	  command to set the kernel for the next boot to
	  <filename class="directory">/boot/GENERIC</filename> (which
	  was updated):</para>

	<screen>&prompt.root; <userinput>nextboot -k GENERIC</userinput></screen>

	<warning>
	  <para>Before rebooting with the <filename>GENERIC</filename>
	    kernel, make sure it contains all drivers required for
	    your system to boot properly (and connect to the network,
	    if the machine that is being updated is accessed
	    remotely).  In particular, if the previously running
	    custom kernel contained built-in functionality usually
	    provided by kernel modules, make sure to temporarily load
	    these modules into the <filename>GENERIC</filename> kernel
	    using the <filename>/boot/loader.conf</filename> facility.
	    You may also wish to disable non-essential services, disk
	    and network mounts, etc. until the upgrade process is
	    complete.</para>
	</warning>

	<para>The machine should now be restarted with the updated
	  kernel:</para>

	<screen>&prompt.root; <userinput>shutdown -r now</userinput></screen>

	<para>Once the system has come back online,
	  <command>freebsd-update</command> will need to be started
	  again.  The state of the process has been saved and thus,
	  <command>freebsd-update</command> will not start from the
	  beginning, but will remove all old shared libraries and
	  object files.  To continue to this stage, issue the
	  following command:</para>

	<screen>&prompt.root; <userinput>freebsd-update install</userinput></screen>

	<note>
	  <para>Depending on whether any libraries version numbers got
	    bumped, there may only be two install phases instead of
	    three.</para>
	</note>
      </sect3>

      <sect3 id="freebsdupdate-portsrebuild">
	<title>Rebuilding Ports After a Major Version Upgrade</title>

	<para>After a major version upgrade, all third party software
	  will now need to be rebuilt and re-installed.  This is
	  required as installed software may depend on libraries which
	  have been removed during the upgrade process.  The
	  <filename role="package">ports-mgmt/portupgrade</filename>
	  command may be used to automate this process.  The following
	  commands may be used to begin this process:</para>

	<screen>&prompt.root; <userinput>portupgrade -f ruby</userinput>
&prompt.root; <userinput>rm /var/db/pkg/pkgdb.db</userinput>
&prompt.root; <userinput>portupgrade -f ruby18-bdb</userinput>
&prompt.root; <userinput>rm /var/db/pkg/pkgdb.db /usr/ports/INDEX-*.db</userinput>
&prompt.root; <userinput>portupgrade -af</userinput></screen>

	<para>Once this has completed, finish the upgrade process with
	  a final call to <command>freebsd-update</command>.  Issue
	  the following command to tie up all loose ends in the
	  upgrade process:</para>

	<screen>&prompt.root; <userinput>freebsd-update install</userinput></screen>

	<para>If the <filename>GENERIC</filename> kernel was
	  temporarily used, this is the time to build and install a
	  new custom kernel in the usual way.</para>

	<para>Reboot the machine into the new &os; version.  The
	  process is complete.</para>
      </sect3>
    </sect2>

    <sect2 id="freebsdupdate-system-comparison">
      <title>System State Comparison</title>

      <para>The <command>freebsd-update</command> utility may be used
	to test the state of the installed &os; version against a
	known good copy.  This option evaluates the current version
	of system utilities, libraries, and configuration files.
	To begin the comparison, issue the following command:</para>

      <screen>&prompt.root; <userinput>freebsd-update IDS &gt;&gt; outfile.ids</userinput></screen>

      <warning>
	<para>While the command name is <acronym>IDS</acronym> it
	  should in no way be a replacement for an intrusion detection
	  system such as
	  <filename role="package">security/snort</filename>.  As
	  <command>freebsd-update</command> stores data on disk, the
	  possibility of tampering is evident.  While this possibility
	  may be reduced by using the
	  <varname>kern.securelevel</varname> setting and storing the
	  <command>freebsd-update</command> data on a read only file
	  system when not in use, a better solution would be to
	  compare the system against a secure disk, such as a
	  <acronym>DVD</acronym> or securely stored external
	  <acronym>USB</acronym> disk device.</para>
      </warning>

      <para>The system will now be inspected, and a list of files
	along with their &man.sha256.1; hash values, both the known
	value in the release and the current installed value, will be
	printed.  This is why the output has been sent to the
	<filename>outfile.ids</filename> file.  It scrolls by too
	quickly for eye comparisons, and soon it fills up the console
	buffer.</para>

      <para>These lines are also extremely long, but the output format
	may be parsed quite easily.  For instance, to obtain a list of
	all files different from those in the release, issue the
	following command:</para>

      <screen>&prompt.root; <userinput>cat outfile.ids | awk '{ print $1 }' | more</userinput>
/etc/master.passwd
/etc/motd
/etc/passwd
/etc/pf.conf</screen>

      <para>This output has been truncated, many more files exist.
	Some of these files have natural modifications, the
	<filename>/etc/passwd</filename> has been modified because
	users have been added to the system.  In some cases, there
	may be other files, such as kernel modules, which differ
	as <command>freebsd-update</command> may have updated them.
	To exclude specific files or directories, add them to the
	<literal>IDSIgnorePaths</literal> option in
	<filename>/etc/freebsd-update.conf</filename>.</para>

      <para>This system may be used as part of an elaborate upgrade
	method, aside from the previously discussed version.</para>
    </sect2>
  </sect1>

  <sect1 id="updating-upgrading-portsnap">
    <sect1info>
      <authorgroup>
	<author>
	  <firstname>Tom</firstname>
	  <surname>Rhodes</surname>
	  <contrib>Written by </contrib>
	</author>
      </authorgroup>
      <authorgroup>
	<author>
	  <firstname>Colin</firstname>
	  <surname>Percival</surname>
	  <contrib>Based on notes provided by </contrib>
	</author>
      </authorgroup>
    </sect1info>
    <title>Portsnap: a Ports Collection Update Tool</title>

    <indexterm><primary>Updating and Upgrading</primary></indexterm>
    <indexterm>
      <primary>Portsnap</primary>
      <see>Updating and Upgrading</see>
    </indexterm>

    <para>The base system of &os; includes a utility for updating
      the Ports Collection too: the &man.portsnap.8; utility.  Upon
      execution, it will connect to a remote site, verify the secure
      key, and download a new copy of the Ports Collection.  The key
      is used to verify the integrity of all downloaded files,
      ensuring they have not been modified in-flight.  To download the
      latest Ports Collection files, issue the following
      command:</para>

    <screen>&prompt.root; <userinput>portsnap fetch</userinput>
Looking up portsnap.FreeBSD.org mirrors... 9 mirrors found.
Fetching snapshot tag from geodns-1.portsnap.freebsd.org... done.
Fetching snapshot metadata... done.
Updating from Tue May 22 02:12:15 CEST 2012 to Wed May 23 16:28:31 CEST 2012.
Fetching 3 metadata patches.. done.
Applying metadata patches... done.
Fetching 3 metadata files... done.
Fetching 90 patches.....10....20....30....40....50....60....70....80....90. done.
Applying patches... done.
Fetching 133 new ports or files... done.</screen>

    <para>What this example shows is that &man.portsnap.8; has found
      and verified several patches to the current ports data.  This
      also indicates that the utility was run previously, if it was a
      first time run, the collection would have simply been
      downloaded.</para>

    <para>When &man.portsnap.8; successfully completes a
      <command>fetch</command> operation, the Ports Collection and
      subsequent patches exist on the local system that have passed
      verification.  The first time <command>portsnap</command> is
      executed, you have to use <literal>extract</literal> to install
      the downloaded files:</para>

    <screen>&prompt.root; <userinput>portsnap extract</userinput>
/usr/ports/.cvsignore
/usr/ports/CHANGES
/usr/ports/COPYRIGHT
/usr/ports/GIDs
/usr/ports/KNOBS
/usr/ports/LEGAL
/usr/ports/MOVED
/usr/ports/Makefile
/usr/ports/Mk/bsd.apache.mk
/usr/ports/Mk/bsd.autotools.mk
/usr/ports/Mk/bsd.cmake.mk
<replaceable>...</replaceable></screen>

    <para>To update an already installed Ports Collection use the
      command <command>portsnap update</command>:</para>

    <screen>&prompt.root; <userinput>portsnap update</userinput></screen>

    <para>The process is now complete, and applications may be
      installed or upgraded using the updated Ports Collection.</para>

    <para>The <literal>fetch</literal> and <literal>extract</literal>
      or <literal>update</literal> operations may be run
      consecutively, as shown in the following example:</para>

    <screen>&prompt.root; <userinput>portsnap fetch update</userinput></screen>

    <para>This command will download the latest version of the
      Ports Collection and update your local version under
      <filename class="directory">/usr/ports</filename>.</para>
  </sect1>

  <sect1 id="updating-upgrading-documentation">
    <title>Updating the Documentation Set</title>

    <indexterm><primary>Updating and Upgrading</primary></indexterm>

    <indexterm>
      <primary>Documentation</primary>
      <see>Updating and Upgrading</see>
    </indexterm>

    <para>Besides the base system and the Ports Collection,
      documentation is an integral part of the &os; operating system.
      While an up-to-date version of the &os; Documentation Set is
      always available on the
      <ulink url="http://www.freebsd.org/doc/">&os; web site</ulink>,
      some users might have slow or no permanent network connectivity
      at all.  Fortunately, there are several ways to update the
      documentation shipped with each release by maintaining a local
      copy of the latest &os; Documentation Set.</para>

    <sect2 id="dsvn-doc">
      <title>Using <application>Subversion</application> to Update the
	Documentation</title>

      <para>The &os; documentation sources can be obtained with
	<application>Subversion</application>.  This section
	describes:</para>

      <itemizedlist>
	<listitem>
	  <para>How to install the documentation toolchain, the tools
	    that are required to rebuild the &os; documentation from
	    its source.</para>
	</listitem>

	<listitem>
	  <para>How to download a copy of the documentation source
	    at <filename class="directory">/usr/doc</filename>,
	    using <application>Subversion</application>.</para>
	</listitem>

	<listitem>
	  <para>How to rebuild the &os; documentation from its source,
	    and install it under <filename
	      class="directory">/usr/share/doc</filename>.</para>
	</listitem>

	<listitem>
	  <para>Some of the build options that are supported by the
	    build system of the documentation, i.e., the options that
	    build only some of the different language translations of
	    the documentation or the options that select a specific
	    output format.</para>
	</listitem>
      </itemizedlist>
    </sect2>

    <sect2 id="installing-documentation-toolchain">
      <title>Installing <application>Subversion</application> and the
	Documentation Toolchain</title>

      <para>Rebuilding the &os; documentation from source requires a
	fairly large collection of tools.  These tools are not part of
	the &os; base system, because they need a large amount of disk
	space and they are not useful to all &os; users; they are only
	useful to those users that are actively writing new
	documentation for &os; or are frequently updating their
	documentation from source.</para>

      <para>All the required tools are available as part of the Ports
	Collection.  The
	<filename role="package">textproc/docproj</filename> port is a
	master port that has been developed by the &os; Documentation
	Project, to ease the initial installation and future updates
	of these tools.</para>

      <note>
	<para>When no &postscript; or PDF documentation required, one
	  might consider installing the <filename
	    role="package">textproc/docproj-nojadetex</filename> port
	  instead.  This version of the documentation toolchain
	  includes everything except the
	  <application>teTeX</application> typesetting engine.
	  <application>teTeX</application> is a very large collection
	  of tools, so it may be quite sensible to omit its
	  installation if PDF output is not really necessary.</para>
      </note>

      <para><application>Subversion</application> is installed with
	the <filename role="package">textproc/docproj</filename>
	port.</para>
    </sect2>

    <sect2 id="updating-documentation-sources">
      <title>Updating the Documentation Sources</title>

      <para>The <application>Subversion</application> program can
	fetch a clean copy of the documentation sources from the
	western US mirror using the HTTPS protocol with this
	command:</para>

      <screen>&prompt.root; <userinput>svn checkout <replaceable>https://svn0.us-west.FreeBSD.org</replaceable>/doc/head /usr/doc</userinput></screen>

      <para>Please use the closest mirror from the available <link
	  linkend="svn-mirrors">Subversion mirror sites</link>.</para>

      <para>The initial download of the documentation sources may take
	a while.  Let it run until it completes.</para>

      <para>Future updates of the documentation sources may be fetched
	by running:</para>

      <screen>&prompt.root; <userinput>svn update <filename class="directory">/usr/doc</filename></userinput></screen>

      <para>After checking out the sources, an alternative way of
	updating the documentation is supported by the
	<filename>Makefile</filename> of the
	<filename class="directory">/usr/doc</filename> directory by
	running:</para>

      <screen>&prompt.root; <userinput>cd /usr/doc</userinput>
&prompt.root; <userinput>make update</userinput></screen>
    </sect2>

    <sect2 id="updating-documentation-options">
      <title>Tunable Options of the Documentation Sources</title>

      <para>The updating and build system of the &os; documentation
	supports a few options that ease the process of updating only
	parts of the documentation, or the build of specific
	translations.  These options can be set either as system-wide
	options in the <filename>/etc/make.conf</filename> file, or as
	command-line options passed to the &man.make.1;
	utility.</para>

      <para>The following options are some of these:</para>

      <variablelist>
	<varlistentry>
	  <term><makevar>DOC_LANG</makevar></term>

	  <listitem>
	    <para>The list of languages and encodings to build and
	      install, e.g., <literal>en_US.ISO8859-1</literal> for
	      the English documentation only.</para>
	  </listitem>
	</varlistentry>

	<varlistentry>
	  <term><makevar>FORMATS</makevar></term>

	  <listitem>
	    <para>A single format or a list of output formats to be
	      built.  Currently, <literal>html</literal>,
	      <literal>html-split</literal>, <literal>txt</literal>,
	      <literal>ps</literal>, <literal>pdf</literal>,
	      and <literal>rtf</literal> are supported.</para>
	  </listitem>
	</varlistentry>

	<varlistentry>
	  <term><makevar>DOCDIR</makevar></term>

	  <listitem>
	    <para>Where to install the documentation.  It defaults to
	      <filename
		class="directory">/usr/share/doc</filename>.</para>
	  </listitem>
	</varlistentry>
      </variablelist>

      <para>For more make variables supported as system-wide options
	in &os;, see &man.make.conf.5;.</para>

      <para>For more make variables supported by the build system of
	the &os; documentation, please refer to the
	<ulink url="&url.doc.langbase;/books/fdp-primer">&os;
	  Documentation Project Primer for New
	  Contributors</ulink>.</para>
    </sect2>

    <sect2 id="updating-installed-documentation">
      <title>Installing the &os; Documentation from Source</title>

      <para>When an up-to-date snapshot of the documentation sources
	has been fetched in
	<filename class="directory">/usr/doc</filename>, everything is
	ready for an update of the installed documentation.</para>

      <para>A full update of all the languages defined in
	the <makevar>DOC_LANG</makevar> makefile option may be done by
	typing:</para>

      <screen>&prompt.root; <userinput>cd /usr/doc</userinput>
&prompt.root; <userinput>make install clean</userinput></screen>

      <para>If an update of only a specific language is desired,
	&man.make.1; can be invoked in a language specific
	subdirectory of
	<filename class="directory">/usr/doc</filename>, i.e.:</para>

      <screen>&prompt.root; <userinput>cd /usr/doc/en_US.ISO8859-1</userinput>
&prompt.root; <userinput>make update install clean</userinput></screen>

      <para>The output formats that will be installed may be specified
	by setting the <makevar>FORMATS</makevar> make variable,
	i.e.:</para>

      <screen>&prompt.root; <userinput>cd /usr/doc</userinput>
&prompt.root; <userinput>make FORMATS='html html-split' install clean</userinput></screen>

      <para>For information on editing and submitting corrections to
	the documentation, please see the <ulink
	  url="&url.books.fdp-primer;">FreeBSD Documentation
	  Project Primer for New Contributors</ulink>.</para>
    </sect2>

    <sect2 id="doc-ports">
      <sect2info>
	<authorgroup>
	  <author>
	    <firstname>Marc</firstname>
	    <surname>Fonvieille</surname>
	    <contrib>Based on the work of </contrib>
	  </author>
	</authorgroup>
      </sect2info>

      <title>Using Documentation Ports</title>

      <indexterm><primary>Updating and Upgrading</primary></indexterm>

      <indexterm>
	<primary>documentation package</primary>
	<see>Updating and Upgrading</see>
      </indexterm>

      <para>In the previous section, we have presented a method for
	updating the &os; documentation from sources.  Source based
	updates may not be feasible or practical for all &os; systems
	though.  Building the documentation sources requires a fairly
	large collection of tools and utilities, the
	<emphasis>documentation toolchain</emphasis>, a certain level
	of familiarity with <application>Subversion</application> and
	source checkouts from a repository, and a few manual steps to
	build the checked out sources.  In this section, we describe
	an alternative way of updating the installed copies of the
	&os; documentation; one that uses the Ports&nbsp;Collection
	and makes it possible to:</para>

      <itemizedlist>
	<listitem>
	  <para>Download and install pre-built snaphots of the
	    documentation, without having to locally build anything
	    (eliminating this way the need for an installation of the
	    entire documentation toolchain).</para>
	</listitem>

	<listitem>
	  <para>Download the documentation sources and build them
	    through the ports framework (making the checkout and build
	    steps a bit eaiser).</para>
	</listitem>
      </itemizedlist>

      <para>These two methods of updating the &os; documentation are
	supported by a set of
	<emphasis>documentation ports</emphasis>, updated by the
	&a.doceng; on a monthly basis.  These are listed in the &os;
	Ports&nbsp;Collection, under the virtual category named <ulink
	  url="http://www.freshports.org/docs/">docs</ulink>.</para>

      <sect3 id="doc-ports-install-make">
	<title>Building and Installing Documentation Ports</title>

	<para>The documentation ports use the ports building framework
	  to make documentation builds easier.  They automate the
	  process of checking out the documentation source, running
	  &man.make.1; with the appropriate environment settings and
	  command-line options, and they make the installation or
	  deinstallation of documentation as easy as the installation
	  of any other &os; port or package.</para>

	<note>
	  <para>As an extra feature, when the documentation ports are
	    built locally, they record a dependency to the
	    <emphasis>documentation toolchain</emphasis> ports, so the
	    latter is automatically installed too.</para>
	</note>

	<para>Organization of the documentation ports is as
	  follows:</para>

	<itemizedlist>
	  <listitem>
	    <para>There is a <quote>master port</quote>,
	      <filename role="package">misc/freebsd-doc-en</filename>,
	      where the documentation port files can be found.  It is
	      the base of all documentation ports.  By default, it
	      builds the English documentation only.</para>
	  </listitem>

	  <listitem>
	    <para>There is an <quote>all in one port</quote>,
	      <filename
		role="package">misc/freebsd-doc-all</filename>, and it
	      builds and installs all documentation in all available
	      languages.</para>
	  </listitem>

	  <listitem>
	    <para>Finally, there is a <quote>slave port</quote> for
	      each translation, e.g.: <filename
		role="package">misc/freebsd-doc-hu</filename> for the
	      Hungarian-language documents.  All of them depend on the
	      master port and install the translated documentation of
	      the respective language.</para>
	  </listitem>
	</itemizedlist>

	<para>To install a documentation port from source, issue the
	  following commands (as <username>root</username>):</para>

	<screen>&prompt.root; <userinput>cd /usr/ports/misc/freebsd-doc-en</userinput>
&prompt.root; <userinput>make install clean</userinput></screen>

	<para>This will build and install the English documentation in
	  split <acronym>HTML</acronym> format (the same as used on
	  <ulink url="http://www.FreeBSD.org"></ulink>) in the
	  <filename
	    class="directory">/usr/local/share/doc/freebsd</filename>
	  directory.</para>

	<sect4 id="doc-ports-options">
	  <title>Common Knobs and Options</title>

	  <para>There are many options for modifying the default
	    behavior of the documentation ports.  The following is
	    just a short list:</para>

	  <variablelist>
	    <varlistentry>
	      <term><makevar>WITH_HTML</makevar></term>

	      <listitem>
		<para>Allows the build of the HTML format: a single
		  HTML file per document.  The formatted documentation
		  is saved to a file called
		  <filename>article.html</filename>, or
		  <filename>book.html</filename>, as appropriate, plus
		  images.</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term><makevar>WITH_PDF</makevar></term>

	      <listitem>
		<para>Allows the build of the &adobe; Portable
		  Document Format, for use with &adobe;
		  &acrobat.reader;,
		  <application>Ghostscript</application> or other PDF
		  readers.  The formatted documentation is saved to a
		  file called <filename>article.pdf</filename> or
		  <filename>book.pdf</filename>, as
		  appropriate.</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term><makevar>DOCBASE</makevar></term>

	      <listitem>
		<para>Where to install the documentation.  It defaults
		  to <filename
		    class="directory">/usr/local/share/doc/freebsd</filename>.</para>

		<note>
		  <para>Notice that the default target directory
		    differs from the directory used by the
		    <application>Subversion</application> method.
		    This is because we are installing a port, and
		    ports are usually installed under the <filename
		      class="directory">/usr/local</filename>
		    directory.  This can be overridden by adding the
		    <makevar>PREFIX</makevar> variable.</para>
		</note>
	      </listitem>
	    </varlistentry>
	  </variablelist>

	  <para>Here is a brief example on how to use the variables
	    mentioned above to install the Hungarian documentation in
	    Portable Document Format:</para>

	  <screen>&prompt.root; cd /usr/ports/misc/freebsd-doc-hu
&prompt.root; make -DWITH_PDF DOCBASE=share/doc/freebsd/hu install clean</screen>
	</sect4>
      </sect3>

      <sect3 id="doc-ports-install-package">
	<title>Using Documentation Packages</title>

	<para>Building the documentation ports from source, as
	  described in the previous section, requires a local
	  installation of the documentation toolchain and a bit of
	  disk space for the build of the ports.  When resources are
	  not available to install the documentation toolchain, or
	  because the build from sources would take too much disk
	  space, it is still possible to install pre-built snapshots
	  of the documentation ports.</para>

	<para>The &a.doceng; prepares monthly snapshots of the &os;
	  documentation packages.  These binary packages can be used
	  with any of the bundled package tools, like &man.pkg.add.1;,
	  &man.pkg.delete.1;, and so on.</para>

	<note>
	  <para>When binary packages are used, the &os; documentation
	    will be installed in <emphasis>all</emphasis> available
	    formats for the given language.</para>
	</note>

	<para>For example, the following command will install the
	  latest pre-built package of the Hungarian
	  documentation:</para>

	<screen>&prompt.root; <userinput>pkg_add -r hu-freebsd-doc</userinput></screen>

	<note>
	  <para>Packages have the following name format that differs
	    from the corresponding port's name:
	    <literal><replaceable>lang</replaceable>-freebsd-doc</literal>.
	    Here <replaceable>lang</replaceable> is the short format
	    of the language code, i.e., <literal>hu</literal> for
	    Hungarian, or <literal>zh_cn</literal> for Simplified
	    Chinese.</para>
	</note>
      </sect3>

      <sect3 id="doc-ports-update">
	<title>Updating Documentation Ports</title>

	<para>To update a previously installed documentation port, any
	  tool suitable for updating ports is sufficient.  For
	  example, the following command updates the installed
	  Hungarian documentation via the
	  <filename role="package">ports-mgmt/portupgrade</filename>
	  tool by using packages only:</para>

	<screen>&prompt.root; <userinput>portupgrade -PP hu-freebsd-doc</userinput></screen>
      </sect3>
    </sect2>
  </sect1>

  <sect1 id="current-stable">
    <title>Tracking a Development Branch</title>

    <indexterm><primary>-CURRENT</primary></indexterm>
    <indexterm><primary>-STABLE</primary></indexterm>

    <para>There are two development branches to FreeBSD: &os.current;
      and &os.stable;.  This section will explain a bit about each and
      describe how to keep your system up-to-date with each respective
      tree.  &os.current; will be discussed first, then
      &os.stable;.</para>

    <sect2 id="current">
      <title>Staying Current with &os;</title>

      <para>As you read this, keep in mind that &os.current; is the
	<quote>bleeding edge</quote> of &os; development.
	&os.current; users are expected to have a high degree of
	technical skill, and should be capable of solving difficult
	system problems on their own.  If you are new to &os;, think
	twice before installing it.</para>

      <sect3>
	<title>What Is &os.current;?</title>

	<indexterm><primary>snapshot</primary></indexterm>

	<para>&os.current; is the latest working sources for &os;.
	  This includes work in progress, experimental changes, and
	  transitional mechanisms that might or might not be present
	  in the next official release of the software.  While many
	  &os; developers compile the &os.current; source code daily,
	  there are periods of time when the sources are not
	  buildable.  These problems are resolved as expeditiously as
	  possible, but whether or not &os.current; brings disaster or
	  greatly desired functionality can be a matter of which exact
	  moment you grabbed the source code in!</para>
      </sect3>

      <sect3>
	<title>Who Needs &os.current;?</title>

	<para>&os.current; is made available for 3 primary
	  interest groups:</para>

	<orderedlist>
	  <listitem>
	    <para>Members of the &os; community who are actively
	      working on some part of the source tree and for whom
	      keeping <quote>current</quote> is an absolute
	      requirement.</para>
	  </listitem>

	  <listitem>
	    <para>Members of the &os; community who are active
	      testers, willing to spend time solving problems in order
	      to ensure that &os.current; remains as sane as possible.
	      These are also people who wish to make topical
	      suggestions on changes and the general direction of
	      &os;, and submit patches to implement them.</para>
	  </listitem>

	  <listitem>
	    <para>Those who merely wish to keep an eye on things, or
	      to use the current sources for reference purposes
	      (e.g., for <emphasis>reading</emphasis>, not running).
	      These people also make the occasional comment or
	      contribute code.</para>
	  </listitem>
	</orderedlist>
      </sect3>

      <sect3>
	<title>What Is &os.current; <emphasis>Not</emphasis>?</title>

	<orderedlist>
	  <listitem>
	    <para>A fast-track to getting pre-release bits because you
	      heard there is some cool new feature in there and you
	      want to be the first on your block to have it.  Being
	      the first on the block to get the new feature means that
	      you are the first on the block to get the new
	      bugs.</para>
	  </listitem>

	  <listitem>
	    <para>A quick way of getting bug fixes.  Any given version
	      of &os.current; is just as likely to introduce new bugs
	      as to fix existing ones.</para>
	  </listitem>

	  <listitem>
	    <para>In any way <quote>officially supported</quote>.  We
	      do our best to help people genuinely in one of the 3
	      <quote>legitimate</quote> &os.current; groups, but we
	      simply <emphasis>do not have the time</emphasis> to
	      provide tech support.  This is not because we are mean
	      and nasty people who do not like helping people out (we
	      would not even be doing &os; if we were).  We simply
	      cannot answer hundreds messages a day
	      <emphasis>and</emphasis> work on FreeBSD!  Given the
	      choice between improving &os; and answering lots of
	      questions on experimental code, the developers opt for
	      the former.</para>
	  </listitem>
	</orderedlist>
      </sect3>

      <sect3>
	<title>Using &os.current;</title>

	<indexterm>
	  <primary>-CURRENT</primary>
	  <secondary>using</secondary>
	</indexterm>
	<orderedlist>
	  <listitem>
	    <para>Join the &a.current.name; and the
	      &a.svn-src-head.name; lists.  This is not just a good
	      idea, it is <emphasis>essential</emphasis>.  If you are
	      not on the <emphasis>&a.current.name;</emphasis> list,
	      you will not see the comments that people are making
	      about the current state of the system and thus will
	      probably end up stumbling over a lot of problems that
	      others have already found and solved.  Even more
	      importantly, you will miss out on important bulletins
	      which may be critical to your system's continued
	      health.</para>

	    <para>The &a.svn-src-head.name; list will allow you to see
	      the commit log entry for each change as it is made,
	      along with any pertinent information on possible
	      side-effects.</para>

	    <para>To join these lists, or one of the others available
	      go to &a.mailman.lists.link; and click on the list that
	      you wish to subscribe to.  Instructions on the rest of
	      the procedure are available there.  If you are
	      interested in tracking changes for the whole source
	      tree, we would recommend subscribing to the
	      &a.svn-src-all.name; list.</para>
	  </listitem>

	  <listitem>
	    <para>Grab the sources from a &os;
	      <link linkend="mirrors">mirror site</link>.  You can do
	      this in one of several ways:</para>

	    <orderedlist>
	      <indexterm>
		<primary>Subversion</primary>
	      </indexterm>
	      <indexterm>
		<primary><command>cron</command></primary>
	      </indexterm>
	      <indexterm>
		<primary>-CURRENT</primary>
		<secondary>Syncing with
		  <application>Subversion</application>
		</secondary>
	      </indexterm>
	      <indexterm>
		<primary>-CURRENT</primary>
		<secondary>Syncing with
		  <application>CTM</application>
		</secondary>
	      </indexterm>

	      <listitem>
		<para>Use the <link linkend="svn">svn</link> program
		  to check out the desired development or release
		  branch.  This is the recommended method, providing
		  access to &os; development as it occurs.  Checkout
		  the -CURRENT code from the <literal>head</literal>
		  branch of one of the
		  <link linkend="svn-mirrors">Subversion mirror
		    sites</link>.  Because of the size of the
		  repository, it is recommended that only desired
		  subtrees be checked out.</para>
	      </listitem>

	      <listitem>
		<indexterm>
		  <primary>-CURRENT</primary>
		  <secondary>Syncing with CTM</secondary>
		</indexterm>

		<para>Use the <application><link
		      linkend="ctm">CTM</link></application> facility.
		  If you have very bad connectivity (high price
		  connections or only email access)
		  <application>CTM</application> is an option.
		  However, it is a lot of hassle and can give you
		  broken files.  This leads to it being rarely used,
		  which again increases the chance of it not working
		  for fairly long periods of time.  We recommend using
		  <application><link
		    linkend="svn">Subversion</link></application> for
		  any system with Internet connectivity.</para>
	      </listitem>
	    </orderedlist>
	  </listitem>

	  <listitem>
	    <para>If you are grabbing the sources to run, and not just
	      look at, then grab <emphasis>all</emphasis> of
	      &os.current;, not just selected portions.  The reason
	      for this is that various parts of the source depend on
	      updates elsewhere, and trying to compile just a subset
	      is almost guaranteed to get you into trouble.</para>

	    <indexterm>
	      <primary>-CURRENT</primary>
	      <secondary>compiling</secondary>
	    </indexterm>
	    <para>Before compiling &os.current;, read the
	      <filename>Makefile</filename> in
	      <filename>/usr/src</filename> carefully.  You should at
	      least <link linkend="makeworld">install a new kernel and
	      rebuild the world</link> the first time through as part
	      of the upgrading process.  Reading the &a.current; and
	      <filename>/usr/src/UPDATING</filename> will keep you
	      up-to-date on other bootstrapping procedures that
	      sometimes become necessary as we move toward the next
	      release.</para>
	  </listitem>

	  <listitem>
	    <para>Be active! If you are running &os.current;, we want
	      to know what you have to say about it, especially if you
	      have suggestions for enhancements or bug fixes.
	      Suggestions with accompanying code are received most
	      enthusiastically!</para>
	  </listitem>
	</orderedlist>
      </sect3>
    </sect2>

    <sect2 id="stable">
      <title>Staying Stable with &os;</title>

      <sect3>
	<title>What Is &os.stable;?</title>

	<indexterm><primary>-STABLE</primary></indexterm>

	<para>&os.stable; is our development branch from which major
	  releases are made.  Changes go into this branch at a
	  different pace, and with the general assumption that they
	  have first gone into &os.current; for testing.  This is
	  <emphasis>still</emphasis> a development branch, however,
	  and this means that at any given time, the sources for
	  &os.stable; may or may not be suitable for any particular
	  purpose.  It is simply another engineering development
	  track, not a resource for end-users.</para>
      </sect3>

      <sect3>
	<title>Who Needs &os.stable;?</title>

	<para>If you are interested in tracking or contributing to the
	  FreeBSD development process, especially as it relates to the
	  next <quote>point</quote> release of FreeBSD, then you
	  should consider following &os.stable;.</para>

	<para>While it is true that security fixes also go into the
	  &os.stable; branch, you do not <emphasis>need</emphasis> to
	  track &os.stable; to do this.  Every security advisory for
	  FreeBSD explains how to fix the problem for the releases it
	  affects

	  <footnote>
	    <para>That is not quite true.  We can not continue
	      to support old releases of FreeBSD forever, although we
	      do support them for many years.  For a complete
	      description of the current security policy for old
	      releases of FreeBSD, please see <ulink
		url="&url.base;/security/">http://www.FreeBSD.org/security/</ulink>.</para></footnote>,
	  and tracking an entire development branch just
	  for security reasons is likely to bring in a lot of unwanted
	  changes as well.</para>

	<para>Although we endeavor to ensure that the &os.stable;
	  branch compiles and runs at all times, this cannot be
	  guaranteed.  In addition, while code is developed in
	  &os.current; before including it in &os.stable;, more people
	  run &os.stable; than &os.current;, so it is inevitable that
	  bugs and corner cases will sometimes be found in &os.stable;
	  that were not apparent in &os.current;.</para>

	<para>For these reasons, we do <emphasis>not</emphasis>
	  recommend that you blindly track &os.stable;, and it is
	  particularly important that you do not update any production
	  servers to &os.stable; without first thoroughly testing the
	  code in your development environment.</para>

	<para>If you do not have the resources to do this then we
	  recommend that you run the most recent release of FreeBSD,
	  and use the binary update mechanism to move from release to
	  release.</para>
      </sect3>

      <sect3>
	<title>Using &os.stable;</title>

	<indexterm>
	  <primary>-STABLE</primary>
	  <secondary>using</secondary>
	</indexterm>
	<orderedlist>
	  <listitem>
	    <para>Join the &a.stable.name; list.  This will keep you
	      informed of build-dependencies that may appear in
	      &os.stable; or any other issues requiring special
	      attention.  Developers will also make announcements in
	      this mailing list when they are contemplating some
	      controversial fix or update, giving the users a chance
	      to respond if they have any issues to raise concerning
	      the proposed change.</para>

	    <para>Join the relevant <application>SVN</application>
	      list for the branch you are tracking.  For example, if
	      you are tracking the 9-STABLE branch, join the
	      &a.svn-src-stable-9.name; list.  This will allow you to
	      view the commit log entry for each change as it is made,
	      along with any pertinent information on possible
	      side-effects.</para>

	    <para>To join these lists, or one of the others available
	      go to &a.mailman.lists.link; and click on the list that
	      you wish to subscribe to.  Instructions on the rest of
	      the procedure are available there.  If you are
	      interested in tracking changes for the whole source
	      tree, we would recommend subscribing to the
	      &a.svn-src-all.name; list.</para>
	  </listitem>

	  <listitem>
	    <para>If you are going to install a new system and want it
	      to run monthly snapshot built from &os.stable;, please
	      check the
	      <ulink url="&url.base;/snapshots/">Snapshots</ulink> web
	      page for more information.  Alternatively, it is
	      possible to install the most recent &os.stable; release
	      from the <link linkend="mirrors">mirror sites</link> and
	      follow the instructions below to upgrade your system to
	      the most up to date &os.stable; source code.</para>

	    <para>If you are already running a previous release of
	      &os; and wish to upgrade via sources then you can easily
	      do so from a &os;
	      <link linkend="mirrors">mirror site</link>.  This can be
	      done in one of several ways:</para>

	    <orderedlist>
	      <indexterm>
		<primary>Subversion</primary>
	      </indexterm>
	      <indexterm>
		<primary><command>cron</command></primary>
	      </indexterm>
	      <indexterm>
		<primary>-STABLE</primary>
		<secondary>syncing with
		  <application>Subversion</application></secondary>
	      </indexterm>

	      <listitem>
		<para>Use the <link linkend="svn">svn</link> program
		  to check out the desired development or release
		  branch.  This is the recommended method, providing
		  access to &os; development as it occurs.  Branch
		  names include <literal>head</literal> for the
		  current development head, and branches identified in
		  <ulink url="&url.base;/releng/">the release
		    engineering page</ulink>, such as
		  <literal>stable/9</literal> or
		  <literal>releng/9.0</literal>.  URL
		  prefixes for <application>Subversion</application>
		  checkout of the base system are shown in <link
		    linkend="svn-mirrors">Subversion mirror
		    sites</link>.
		  Because of the size of the repository, it is
		  recommended that only desired subtrees be checked
		  out.</para>
	      </listitem>

	      <listitem>
		<indexterm>
		  <primary>-STABLE</primary>
		  <secondary>syncing with CTM</secondary>
		</indexterm>

		<para>Use the <application><link
		      linkend="ctm">CTM</link></application> facility.
		  If you do not have a fast and inexpensive connection
		  to the Internet, this is the method you should
		  consider using.</para>
	      </listitem>
	    </orderedlist>
	  </listitem>

	  <listitem>
	    <para>Essentially, if you need rapid on-demand access to
	      the source and communications bandwidth is not a
	      consideration, use
	      <application>Subversion</application>.  Otherwise, use
	      <application>CTM</application>.</para>
	  </listitem>

	  <listitem>
	    <indexterm>
	      <primary>-STABLE</primary>
	      <secondary>compiling</secondary>
	    </indexterm>

	    <para>Before compiling &os.stable;, read the
	      <filename>Makefile</filename> in
	      <filename>/usr/src</filename> carefully.  You should at
	      least <link linkend="makeworld">install a new kernel and
	      rebuild the world</link> the first time through as part
	      of the upgrading process.  Reading the &a.stable; and
	      <filename>/usr/src/UPDATING</filename> will keep you
	      up-to-date on other bootstrapping procedures that
	      sometimes become necessary as we move toward the next
	      release.</para>
	  </listitem>
	</orderedlist>
      </sect3>
    </sect2>
  </sect1>

  <sect1 id="synching">
    <title>Synchronizing Your Source</title>

    <para>There are various ways of using an Internet (or email)
      connection to stay up-to-date with any given area of the &os;
      project sources, or all areas, depending on what interests you.
      The primary services we offer are
      <link linkend="svn">Subversion</link> and
      <link linkend="ctm">CTM</link>.</para>

    <warning>
      <para>While it is possible to update only parts of your source
	tree, the only supported update procedure is to update the
	entire tree and recompile both userland (i.e., all the
	programs that run in user space, such as those in
	<filename>/bin</filename> and <filename>/sbin</filename>) and
	kernel sources.  Updating only part of your source tree, only
	the kernel, or only userland will often result in problems.
	These problems may range from compile errors to kernel panics
	or data corruption.</para>
    </warning>

    <indexterm>
      <primary>Subversion</primary>
    </indexterm>

    <para><application>Subversion</application> uses the
      <emphasis>pull</emphasis> model of updating sources.  The user
      (or a <command>cron</command> script) invokes the
      <command>svn</command> program, and it brings files up-to-date.
      <application>Subversion</application> is the preferred means of
      updating local source trees.  The updates you receive are
      up-to-the-minute and you get them when, and only when, you want
      them.  You can easily restrict your updates to the specific
      files or directories that are of interest to you.  Updates are
      generated on the fly by the server, according to what you have
      and what you want to have.</para>

    <indexterm>
      <primary><application>CTM</application></primary>
    </indexterm>
    <para><application>CTM</application>, on the other hand, does not
      interactively compare the sources you have with those on the
      master archive or otherwise pull them across.  Instead, a script
      which identifies changes in files since its previous run is
      executed several times a day on the master CTM machine, any
      detected changes being compressed, stamped with a
      sequence-number and encoded for transmission over email (in
      printable ASCII only).  Once received, these
      <quote>CTM deltas</quote> can then be handed to the
      &man.ctm.rmail.1; utility which will automatically decode,
      verify and apply the changes to the user's copy of the sources.
      This process is far more efficient than
      <application>Subversion</application>, and places less strain on
      our server resources since it is a <emphasis>push</emphasis>
      rather than a <emphasis>pull</emphasis> model.</para>

    <para>There are other trade-offs, of course.  If you inadvertently
      wipe out portions of your archive,
      <application>Subversion</application> will detect and rebuild
      the damaged portions for you.  <application>CTM</application>
      will not do this, and if you wipe some portion of your source
      tree out (and do not have it backed up) then you will have to
      start from scratch (from the most recent CTM
      <quote>base delta</quote>) and rebuild it all with
      <application>CTM</application>.</para>
  </sect1>

  <sect1 id="makeworld">
    <title>Rebuilding <quote>world</quote></title>

    <indexterm>
      <primary>Rebuilding <quote>world</quote></primary>
    </indexterm>
    <para>Once you have synchronized your local source tree against a
      particular version of &os; (&os.stable;, &os.current;, and so
      on) you can then use the source tree to rebuild the
      system.</para>

    <warning>
      <title>Make a Backup</title>

      <para>It cannot be stressed enough how important it is to make a
	backup of your system <emphasis>before</emphasis> you do this.
	While rebuilding the world is (as long as you follow these
	instructions) an easy task to do, there will inevitably be
	times when you make mistakes, or when mistakes made by others
	in the source tree render your system unbootable.</para>

      <para>Make sure you have taken a backup.  And have a fixit
	floppy or bootable CD at hand.  You will probably never have
	to use it, but it is better to be safe than sorry!</para>
    </warning>

    <warning>
      <title>Subscribe to the Right Mailing List</title>

      <indexterm><primary>mailing list</primary></indexterm>
      <para>The &os.stable; and &os.current; branches are, by their
	nature, <emphasis>in development</emphasis>.  People that
	contribute to &os; are human, and mistakes occasionally
	happen.</para>

      <para>Sometimes these mistakes can be quite harmless, just
	causing your system to print a new diagnostic warning.  Or the
	change may be catastrophic, and render your system unbootable
	or destroy your file systems (or worse).</para>

      <para>If problems like these occur, a <quote>heads up</quote> is
	posted to the appropriate mailing list, explaining the nature
	of the problem and which systems it affects.  And an
	<quote>all clear</quote> announcement is posted when the
	problem has been solved.</para>

      <para>If you try to track &os.stable; or &os.current; and do
	not read the &a.stable; or the &a.current; respectively, then
	you are asking for trouble.</para>
    </warning>

    <warning>
      <title>Do Not Use <command>make world</command></title>

      <para>A lot of older documentation recommends using
	<command>make world</command> for this.  Doing that skips
	some important steps and should only be used if you are
	sure of what you are doing.  For almost all circumstances
	<command>make world</command> is the wrong thing to do, and
	the procedure described here should be used instead.</para>
    </warning>

    <sect2 id="canonical-build">
      <title>The Canonical Way to Update Your System</title>

      <para>To update your system, you should check
	<filename>/usr/src/UPDATING</filename> for any pre-buildworld
	steps necessary for your version of the sources and then use
	the procedure outlined here.</para>

      <para>These upgrade steps assume that you are currently using an
	old &os; version, consisting of an old compiler, old kernel,
	old world and old configuration files.  By
	<quote>world</quote> here we mean the core system binaries,
	libraries and programming files.  The compiler is part of
	<quote>world</quote>, but has a few special concerns.</para>

      <para>We also assume that you have already obtained the sources
	to a newer system.  If the sources available on the particular
	system are old too, see <xref linkend="synching"/> for
	detailed help about synchronizing them to a newer
	version.</para>

      <para>Updating the system from sources is a bit more subtle than
	it might initially seem to be, and the &os; developers have
	found it necessary over the years to change the recommended
	approach fairly dramatically as new kinds of unavoidable
	dependencies come to light.  The rest of this section
	describes the rationale behind the currently recommended
	upgrade sequence.</para>

      <para>Any successful update sequence must deal with the
	following issues:</para>

      <itemizedlist>
	<listitem>
	  <para>The old compiler might not be able to compile the new
	    kernel.  (Old compilers sometimes have bugs.)  So, the new
	    kernel should be built with the new compiler.  In
	    particular, the new compiler must be built before the new
	    kernel is built.  This does not necessarily mean that the
	    new compiler must be <emphasis>installed</emphasis> before
	    building the new kernel.</para>
	</listitem>

	<listitem>
	  <para>The new world might rely on new kernel features.  So,
	    the new kernel must be installed before the new world is
	    installed.</para>
	</listitem>
      </itemizedlist>

      <para>These first two issues are the basis for the
	core <maketarget>buildworld</maketarget>,
	<maketarget>buildkernel</maketarget>,
	<maketarget>installkernel</maketarget>,
	<maketarget>installworld</maketarget> sequence that we
	describe in the following paragraphs.  This is not an
	exhaustive list of all the reasons why you should prefer the
	currently recommended upgrade process.  Some of the less
	obvious ones are listed below:</para>

      <itemizedlist>
	<listitem>
	  <para>The old world might not run correctly on the new
	    kernel, so you must install the new world immediately upon
	    installing the new kernel.</para>
	</listitem>

	<listitem>
	  <para>Some configuration changes must be done before the new
	    world is installed, but others might break the old world.
	    Hence, two different configuration upgrade steps are
	    generally needed.</para>
	</listitem>

	<listitem>
	  <para>For the most part, the update process only replaces or
	    adds files; existing old files are not deleted.  In a few
	    cases, this can cause problems.  As a result, the update
	    procedure will sometimes specify certain files that should
	    be manually deleted at certain steps.  This may or may not
	    be automated in the future.</para>
	</listitem>
      </itemizedlist>

      <para>These concerns have led to the following recommended
	sequence.  Note that the detailed sequence for particular
	updates may require additional steps, but this core process
	should remain unchanged for some time:</para>

      <orderedlist>
	<listitem>
	  <para><command>make
	      <maketarget>buildworld</maketarget></command></para>

	  <para>This first compiles the new compiler and a few related
	    tools, then uses the new compiler to compile the rest of
	    the new world.  The result ends up in
	    <filename class="directory">/usr/obj</filename>.</para>
	</listitem>

	<listitem>
	  <para><command>make
	      <maketarget>buildkernel</maketarget></command></para>

	  <para>Unlike the older approach, using &man.config.8; and
	    &man.make.1;, this uses the <emphasis>new</emphasis>
	    compiler residing in
	    <filename class="directory">/usr/obj</filename>.  This
	    protects you against compiler-kernel mismatches.</para>
	</listitem>

	<listitem>
	  <para><command>make
	      <maketarget>installkernel</maketarget></command></para>

	  <para>Place the new kernel and kernel modules onto the disk,
	    making it possible to boot with the newly updated
	    kernel.</para>
	</listitem>

	<listitem>
	  <para>Reboot into single user mode.</para>

	  <para>Single user mode minimizes problems from updating
	    software that is already running.  It also minimizes any
	    problems from running the old world on a new
	    kernel.</para>
	</listitem>

	<listitem>
	  <para><command>mergemaster
	      <option>-p</option></command></para>

	  <para>This does some initial configuration file updates in
	    preparation for the new world.  For instance it may add
	    new user groups to the system, or new user names to the
	    password database.  This is often necessary when new
	    groups or special system-user accounts have been added
	    since the last update, so that the
	    <maketarget>installworld</maketarget> step will be able to
	    use the newly installed system user or system group names
	    without problems.</para>
	</listitem>

	<listitem>
	  <para><command>make
	      <maketarget>installworld</maketarget></command></para>

	  <para>Copies the world
	    from <filename class="directory">/usr/obj</filename>.  You
	    now have a new kernel and new world on disk.</para>
	</listitem>

	<listitem>
	  <para><command>mergemaster</command></para>

	  <para>Now you can update the remaining configuration files,
	    since you have a new world on disk.</para>
	</listitem>

	<listitem>
	  <para>Reboot.</para>

	  <para>A full machine reboot is needed now to load the new
	    kernel and new world with new configuration files.</para>
	</listitem>
      </orderedlist>

      <para>Note that if you are upgrading from one release of the
	same &os; branch to a more recent release of the same branch,
	i.e., from 7.0 to 7.1, then this procedure may not be
	absolutely necessary, since you are unlikely to run into
	serious mismatches between compiler, kernel, userland and
	configuration files.  The older approach of
	<command>make <maketarget>world</maketarget></command>
	followed by building and installing a new kernel might work
	well enough for minor updates.</para>

      <para>But, when upgrading across major releases, people who do
	not follow this procedure should expect some problems.</para>

      <para>It is also worth noting that many upgrades
	(i.e.,&nbsp;4.<replaceable>X</replaceable> to 5.0) may require
	specific additional steps (renaming or deleting specific files
	prior to installworld, for instance).  Read the
	<filename>/usr/src/UPDATING</filename> file carefully,
	especially at the end, where the currently recommended upgrade
	sequence is explicitly spelled out.</para>

      <para>This procedure has evolved over time as the developers
	have found it impossible to completely prevent certain kinds
	of mismatch problems.  Hopefully, the current procedure will
	remain stable for a long time.</para>

      <para>To summarize, the currently recommended way of upgrading
	&os; from sources is:</para>

      <screen>&prompt.root; <userinput>cd /usr/src</userinput>
&prompt.root; <userinput>make buildworld</userinput>
&prompt.root; <userinput>make buildkernel</userinput>
&prompt.root; <userinput>make installkernel</userinput>
&prompt.root; <userinput>shutdown -r now</userinput></screen>

      <note>
	<para>There are a few rare cases when an extra run of
	  <command>mergemaster -p</command> is needed before the
	  <maketarget>buildworld</maketarget> step.  These are
	  described in <filename>UPDATING</filename>.  In general,
	  though, you can safely omit this step if you are not
	  updating across one or more major &os; versions.</para>
      </note>

      <para>After <maketarget>installkernel</maketarget> finishes
	successfully, you should boot in single user mode
	(i.e.,&nbsp;using <command>boot -s</command> from the loader
	prompt).  Then run:</para>

      <screen>&prompt.root; <userinput>mount -u /</userinput>
&prompt.root; <userinput>mount -a -t ufs</userinput>
&prompt.root; <userinput>adjkerntz -i</userinput>
&prompt.root; <userinput>mergemaster -p</userinput>
&prompt.root; <userinput>cd /usr/src</userinput>
&prompt.root; <userinput>make installworld</userinput>
&prompt.root; <userinput>mergemaster</userinput>
&prompt.root; <userinput>reboot</userinput></screen>

      <warning>
	<title>Read Further Explanations</title>

	<para>The sequence described above is only a short resume to
	  help you getting started.  You should however read the
	  following sections to clearly understand each step,
	  especially if you want to use a custom kernel
	  configuration.</para>
      </warning>
    </sect2>

    <sect2 id="src-updating">
      <title>Read <filename>/usr/src/UPDATING</filename></title>

      <para>Before you do anything else, read
	<filename>/usr/src/UPDATING</filename> (or the equivalent file
	wherever you have a copy of the source code).  This file
	should contain important information about problems you might
	encounter, or specify the order in which you might have to run
	certain commands.  If <filename>UPDATING</filename>
	contradicts something you read here,
	<filename>UPDATING</filename> takes precedence.</para>

      <important>
	<para>Reading <filename>UPDATING</filename> is not an
	  acceptable substitute for subscribing to the correct mailing
	  list, as described previously.  The two requirements are
	  complementary, not exclusive.</para>
      </important>
    </sect2>

    <sect2 id="make-conf">
      <title>Check <filename>/etc/make.conf</filename></title>

      <indexterm>
	<primary><filename>make.conf</filename></primary>
      </indexterm>

      <para>&man.make.1; options are shown in &man.make.conf.5; and
	<filename>/usr/share/examples/etc/make.conf</filename>.  These
	settings can be added to <filename>/etc/make.conf</filename>
	to control the way &man.make.1; runs and how it builds
	programs.  Changes to some settings can have far-reaching and
	potentially surprising effects.  Read the comments in both
	locations and keep in mind that the defaults have been chosen
	for a combination of performance and safety.</para>

      <para>Options set in <filename>/etc/make.conf</filename> take
	effect every time &man.make.1; is used, including compiling
	applications from the Ports Collection or user-written C
	programs, or building the &os; operating system itself.</para>
    </sect2>

    <sect2 id="src-conf">
      <title>Check <filename>/etc/src.conf</filename></title>

      <indexterm>
	<primary><filename>src.conf</filename></primary>
      </indexterm>

      <para><filename>/etc/src.conf</filename> controls the building
	of the operating system from source code.  Unlike
	<filename>/etc/make.conf</filename>, the contents of
	<filename>/etc/src.conf</filename> only take effect when the
	&os; operating system itself is being built.  Descriptions of
	the many options available for this file are shown in
	&man.src.conf.5;.  Be cautious about disabling seemingly
	unneeded kernel modules and build options.  Sometimes there
	are unexpected or subtle interactions.</para>
    </sect2>

    <sect2 id="updating-etc">
      <title>Update the Files in <filename>/etc</filename></title>

      <para>The <filename>/etc</filename> directory contains a large
	part of your system's configuration information, as well as
	scripts that are run at system startup.  Some of these scripts
	change from version to version of FreeBSD.</para>

      <para>Some of the configuration files are also used in the day
	to day running of the system.  In particular,
	<filename>/etc/group</filename>.</para>

      <para>There have been occasions when the installation part of
	<command>make installworld</command> has expected certain
	usernames or groups to exist.  When performing an upgrade it
	is likely that these users or groups did not exist.  This
	caused problems when upgrading.  In some cases
	<command>make buildworld</command> will check to see if these
	users or groups exist.</para>

      <para>An example of this is when the <username>smmsp</username>
	user was added.  Users had the installation process fail for
	them when &man.mtree.8; was trying to create
	<filename>/var/spool/clientmqueue</filename>.</para>

      <para>The solution is to run &man.mergemaster.8; in
	pre-buildworld mode by providing the <option>-p</option>
	option.  This will compare only those files that are essential
	for the success of <maketarget>buildworld</maketarget> or
	<maketarget>installworld</maketarget>.</para>

      <tip>
	<para>If you are feeling particularly paranoid, you can check
	  your system to see which files are owned by the group you
	  are renaming or deleting:</para>

	<screen>&prompt.root; <userinput>find / -group <replaceable>GID</replaceable> -print</userinput></screen>

	<para>will show all files owned by group
	  <replaceable>GID</replaceable> (which can be either a group
	  name or a numeric group ID).</para>
      </tip>
    </sect2>

    <sect2 id="makeworld-singleuser">
      <title>Drop to Single User Mode</title>

      <indexterm><primary>single-user mode</primary></indexterm>

      <para>You may want to compile the system in single user mode.
	Apart from the obvious benefit of making things go slightly
	faster, reinstalling the system will touch a lot of important
	system files, all the standard system binaries, libraries,
	include files and so on.  Changing these on a running system
	(particularly if you have active users on the system at the
	time) is asking for trouble.</para>

      <indexterm><primary>multi-user mode</primary></indexterm>
      <para>Another method is to compile the system in multi-user
	mode, and then drop into single user mode for the
	installation.  If you would like to do it this way, simply
	hold off on the following steps until the build has completed.
	You can postpone dropping to single user mode until you have
	to <maketarget>installkernel</maketarget> or
	<maketarget>installworld</maketarget>.</para>

      <para>As the superuser, you can execute:</para>

      <screen>&prompt.root; <userinput>shutdown now</userinput></screen>

      <para>from a running system, which will drop it to single user
	mode.</para>

      <para>Alternatively, reboot the system, and at the boot prompt,
	select the <quote>single user</quote> option.  The system will
	then boot single user.  At the shell prompt you should then
	run:</para>

      <screen>&prompt.root; <userinput>fsck -p</userinput>
&prompt.root; <userinput>mount -u /</userinput>
&prompt.root; <userinput>mount -a -t ufs</userinput>
&prompt.root; <userinput>swapon -a</userinput></screen>

      <para>This checks the file systems, remounts
	<filename>/</filename> read/write, mounts all the other UFS
	file systems referenced in <filename>/etc/fstab</filename> and
	then turns swapping on.</para>

      <note>
	<para>If your CMOS clock is set to local time and not to GMT
	  (this is true if the output of the &man.date.1; command
	  does not show the correct time and zone),
	  you may also need to run the following command:</para>

	<screen>&prompt.root; <userinput>adjkerntz -i</userinput></screen>

	<para>This will make sure that your local time-zone settings
	  get set up correctly &mdash; without this, you may later run
	  into some problems.</para>
      </note>
    </sect2>

    <sect2 id="cleaning-usr-obj">
      <title>Remove <filename>/usr/obj</filename></title>

      <para>As parts of the system are rebuilt they are placed in
	directories which (by default) go under
	<filename>/usr/obj</filename>.  The directories shadow those
	under <filename>/usr/src</filename>.</para>

      <para>You can speed up the <command>make buildworld</command>
	process, and possibly save yourself some dependency headaches
	by removing this directory as well.</para>

      <para>Some files below <filename>/usr/obj</filename> may have
	the immutable flag set (see &man.chflags.1; for more
	information) which must be removed first.</para>

      <screen>&prompt.root; <userinput>cd /usr/obj</userinput>
&prompt.root; <userinput>chflags -R noschg *</userinput>
&prompt.root; <userinput>rm -rf *</userinput></screen>
    </sect2>

    <sect2 id="updating-upgrading-compilebase">
      <title>Recompile the Base System</title>

      <sect3>
	<title>Saving the Output</title>

	<para>It is a good idea to save the output you get from
	  running &man.make.1; to another file.  If something goes
	  wrong you will have a copy of the error message.  While this
	  might not help you in diagnosing what has gone wrong, it can
	  help others if you post your problem to one of the &os;
	  mailing lists.</para>

	<para>The easiest way to do this is to use the &man.script.1;
	  command, with a parameter that specifies the name of the
	  file to save all output to.  You would do this immediately
	  before rebuilding the world, and then type
	  <userinput>exit</userinput> when the process has
	  finished.</para>

	<screen>&prompt.root; <userinput>script /var/tmp/mw.out</userinput>
Script started, output file is /var/tmp/mw.out
&prompt.root; <userinput>make TARGET</userinput>
<emphasis>&hellip; compile, compile, compile &hellip;</emphasis>
&prompt.root; <userinput>exit</userinput>
Script done, &hellip;</screen>

	<para>If you do this, <emphasis>do not</emphasis> save the
	  output in <filename>/tmp</filename>.  This directory may be
	  cleared next time you reboot.  A better place to store it is
	  in <filename>/var/tmp</filename> (as in the previous
	  example) or in <username>root</username>'s home
	  directory.</para>
      </sect3>

      <sect3 id="make-buildworld">
	<title>Compile the Base System</title>

	<para>You must be in the <filename>/usr/src</filename>
	  directory:</para>

	<screen>&prompt.root; <userinput>cd /usr/src</userinput></screen>

	<para>(unless, of course, your source code is elsewhere, in
	  which case change to that directory instead).</para>

	<indexterm><primary><command>make</command></primary></indexterm>

	<para>To rebuild the world you use the &man.make.1; command.
	  This command reads instructions from the
	  <filename>Makefile</filename>, which describes how the
	  programs that comprise &os; should be rebuilt, the order in
	  which they should be built, and so on.</para>

	<para>The general format of the command line you will type is
	  as follows:</para>

	<screen>&prompt.root; <userinput>make -<replaceable>x</replaceable> -D<replaceable>VARIABLE</replaceable> <replaceable>target</replaceable></userinput></screen>

	<para>In this example,
	  <option>-<replaceable>x</replaceable></option> is an option
	  that you would pass to &man.make.1;.  See the &man.make.1;
	  manual page for an example of the options you can
	  pass.</para>

	<para><option>-D<replaceable>VARIABLE</replaceable></option>
	  passes a variable to the <filename>Makefile</filename>.  The
	  behavior of the <filename>Makefile</filename> is controlled
	  by these variables.  These are the same variables as are set
	  in <filename>/etc/make.conf</filename>, and this provides
	  another way of setting them.</para>

	<screen>&prompt.root; <userinput>make -DNO_PROFILE <replaceable>target</replaceable></userinput></screen>

	<para>is another way of specifying that profiled libraries
	  should not be built, and corresponds with the</para>

	<programlisting>NO_PROFILE=    true     #    Avoid compiling profiled libraries</programlisting>

	<para>line in <filename>/etc/make.conf</filename>.</para>

	<para><replaceable>target</replaceable> tells &man.make.1;
	  what you want to do.  Each <filename>Makefile</filename>
	  defines a number of different <quote>targets</quote>, and
	  your choice of target determines what happens.</para>

	<para>Some targets are listed in the
	  <filename>Makefile</filename>, but are not meant for you to
	  run.  Instead, they are used by the build process to break
	  out the steps necessary to rebuild the system into a number
	  of sub-steps.</para>

	<para>Most of the time you will not need to pass any
	  parameters to &man.make.1;, and so your command like will
	  look like this:</para>

	<screen>&prompt.root; <userinput>make <replaceable>target</replaceable></userinput></screen>

	<para>Where <replaceable>target</replaceable> will be one of
	  many build options.  The first target should always be
	  <makevar>buildworld</makevar>.</para>

	<para>As the names imply, <maketarget>buildworld</maketarget>
	  builds a complete new tree under
	  <filename>/usr/obj</filename>, and
	  <maketarget>installworld</maketarget>, another target,
	  installs this tree on the current machine.</para>

	<para>Having separate options is very useful for two reasons.
	  First, it allows you to do the build safe in the knowledge
	  that no components of your running system will be affected.
	  The build is <quote>self hosted</quote>.  Because of this,
	  you can safely run <maketarget>buildworld</maketarget> on a
	  machine running in multi-user mode with no fear of
	  ill-effects.  It is still recommended that you run the
	  <maketarget>installworld</maketarget> part in single user
	  mode, though.</para>

	<para>Secondly, it allows you to use NFS mounts to upgrade
	  multiple machines on your network.  If you have three
	  machines, <hostid>A</hostid>, <hostid>B</hostid> and
	  <hostid>C</hostid> that you want to upgrade, run
	  <command>make buildworld</command> and
	  <command>make installworld</command> on <hostid>A</hostid>.
	  <hostid>B</hostid> and <hostid>C</hostid> should then NFS
	  mount <filename>/usr/src</filename> and
	  <filename>/usr/obj</filename> from <hostid>A</hostid>, and
	  you can then run <command>make installworld</command> to
	  install the results of the build on <hostid>B</hostid> and
	  <hostid>C</hostid>.</para>

	<para>Although the <maketarget>world</maketarget> target still
	  exists, you are strongly encouraged not to use it.</para>

	<para>Run</para>

	<screen>&prompt.root; <userinput>make buildworld</userinput></screen>

	<para>It is possible to specify a <option>-j</option> option
	  to <command>make</command> which will cause it to spawn
	  several simultaneous processes.  This is most useful on
	  multi-CPU machines.  However, since much of the compiling
	  process is IO bound rather than CPU bound it is also useful
	  on single CPU machines.</para>

	<para>On a typical single-CPU machine you would run:</para>

	<screen>&prompt.root; <userinput>make -j4 buildworld</userinput></screen>

	<para>&man.make.1; will then have up to 4 processes running at
	  any one time.  Empirical evidence posted to the mailing
	  lists shows this generally gives the best performance
	  benefit.</para>

	<para>If you have a multi-CPU machine and you are using an SMP
	  configured kernel try values between 6 and 10 and see how
	  they speed things up.</para>
      </sect3>

      <sect3>
	<title>Timings</title>

	<indexterm>
	  <primary>rebuilding <quote>world</quote></primary>
	  <secondary>timings</secondary>
	</indexterm>

	<para>Many factors influence the build time, but fairly recent
	  machines may only take a one or two hours to build the
	  &os.stable; tree, with no tricks or shortcuts used during
	  the process.  A &os.current; tree will take somewhat
	  longer.</para>
      </sect3>
    </sect2>

    <sect2 id="new-kernel">
      <title>Compile and Install a New Kernel</title>

      <indexterm>
	<primary>kernel</primary>
	<secondary>compiling</secondary>
      </indexterm>

      <para>To take full advantage of your new system you should
	recompile the kernel.  This is practically a necessity, as
	certain memory structures may have changed, and programs like
	&man.ps.1; and &man.top.1; will fail to work until the kernel
	and source code versions are the same.</para>

      <para>The simplest, safest way to do this is to build and
	install a kernel based on <filename>GENERIC</filename>.  While
	<filename>GENERIC</filename> may not have all the necessary
	devices for your system, it should contain everything
	necessary to boot your system back to single user mode.  This
	is a good test that the new system works properly.  After
	booting from <filename>GENERIC</filename> and verifying that
	your system works you can then build a new kernel based on
	your normal kernel configuration file.</para>

      <para>On &os; it is important to
	<link linkend="make-buildworld">build world</link> before
	building a new kernel.</para>

      <note>
	<para>If you want to build a custom kernel, and already have a
	  configuration file, just use
	  <literal>KERNCONF=<replaceable>MYKERNEL</replaceable></literal>
	  like this:</para>

	<screen>&prompt.root; <userinput>cd /usr/src</userinput>
&prompt.root; <userinput>make buildkernel KERNCONF=<replaceable>MYKERNEL</replaceable></userinput>
&prompt.root; <userinput>make installkernel KERNCONF=<replaceable>MYKERNEL</replaceable></userinput></screen>
      </note>

      <para>Note that if you have raised
	<literal>kern.securelevel</literal> above 1
	<emphasis>and</emphasis> you have set either the
	<literal>noschg</literal> or similar flags to your kernel
	binary, you might find it necessary to drop into single user
	mode to use <maketarget>installkernel</maketarget>.  Otherwise
	you should be able to run both these commands from multi user
	mode without problems.  See &man.init.8; for details about
	<literal>kern.securelevel</literal> and &man.chflags.1; for
	details about the various file flags.</para>
    </sect2>

    <sect2 id="new-kernel-singleuser">
      <title>Reboot into Single User Mode</title>

      <indexterm><primary>single-user mode</primary></indexterm>

      <para>You should reboot into single user mode to test the new
	kernel works.  Do this by following the instructions in
	<xref linkend="makeworld-singleuser"/>.</para>
    </sect2>

    <sect2 id="make-installworld">
      <title>Install the New System Binaries</title>

      <para>You should now use <maketarget>installworld</maketarget>
	to install the new system binaries.</para>

      <para>Run</para>

      <screen>&prompt.root; <userinput>cd /usr/src</userinput>
&prompt.root; <userinput>make installworld</userinput></screen>

      <note>
	<para>If you specified variables on the
	  <command>make buildworld</command> command line, you must
	  specify the same variables in the
	  <command>make installworld</command> command line.  This
	  does not necessarily hold true for other options; for
	  example, <option>-j</option> must never be used with
	  <maketarget>installworld</maketarget>.</para>

	<para>For example, if you ran:</para>

	<screen>&prompt.root; <userinput>make -DNO_PROFILE buildworld</userinput></screen>

	<para>you must install the results with:</para>

	<screen>&prompt.root; <userinput>make -DNO_PROFILE installworld</userinput></screen>

	<para>otherwise it would try to install profiled libraries
	  that had not been built during the
	  <command>make buildworld</command> phase.</para>
      </note>
    </sect2>

    <sect2 id="post-installworld-updates">
      <title>Update Files Not Updated by
	<command>make installworld</command></title>

      <para>Remaking the world will not update certain directories (in
	particular, <filename>/etc</filename>,
	<filename>/var</filename> and <filename>/usr</filename>) with
	new or changed configuration files.</para>

      <para>The simplest way to update these files is to use
	&man.mergemaster.8;, though it is possible to do it manually
	if you would prefer to do that.  Regardless of which way you
	choose, be sure to make a backup of <filename>/etc</filename>
	in case anything goes wrong.</para>

      <sect3 id="mergemaster">
	<sect3info>
	  <authorgroup>
	    <author>
	      <firstname>Tom</firstname>
	      <surname>Rhodes</surname>
	      <contrib>Contributed by </contrib>
	    </author>
	  </authorgroup>
	</sect3info>
	<title><command>mergemaster</command></title>

	<indexterm>
	  <primary>
	    <command>mergemaster</command>
	  </primary>
	</indexterm>

	<para>The &man.mergemaster.8; utility is a Bourne script that
	  will aid you in determining the differences between your
	  configuration files in <filename>/etc</filename>, and the
	  configuration files in the source tree
	  <filename>/usr/src/etc</filename>.  This is the recommended
	  solution for keeping the system configuration files up to
	  date with those located in the source tree.</para>

	<para>To begin simply type <command>mergemaster</command> at
	  your prompt, and watch it start going.
	  <command>mergemaster</command> will then build a temporary
	  root environment, from <filename>/</filename> down, and
	  populate it with various system configuration files.  Those
	  files are then compared to the ones currently installed in
	  your system.  At this point, files that differ will be shown
	  in &man.diff.1; format, with the <option>+</option> sign
	  representing added or modified lines, and <option>-</option>
	  representing lines that will be either removed completely,
	  or replaced with a new line.  See the &man.diff.1; manual
	  page for more information about the &man.diff.1; syntax and
	  how file differences are shown.</para>

	<para>&man.mergemaster.8; will then show you each file that
	  displays variances, and at this point you will have the
	  option of either deleting the new file (referred to as the
	  temporary file), installing the temporary file in its
	  unmodified state, merging the temporary file with the
	  currently installed file, or viewing the &man.diff.1;
	  results again.</para>

	<para>Choosing to delete the temporary file will tell
	  &man.mergemaster.8; that we wish to keep our current file
	  unchanged, and to delete the new version.  This option is
	  not recommended, unless you see no reason to change the
	  current file.  You can get help at any time by typing
	  <keycap>?</keycap> at the &man.mergemaster.8; prompt.  If
	  the user chooses to skip a file, it will be presented again
	  after all other files have been dealt with.</para>

	<para>Choosing to install the unmodified temporary file will
	  replace the current file with the new one.  For most
	  unmodified files, this is the best option.</para>

	<para>Choosing to merge the file will present you with a text
	  editor, and the contents of both files.  You can now merge
	  them by reviewing both files side by side on the screen, and
	  choosing parts from both to create a finished product.  When
	  the files are compared side by side, the <keycap>l</keycap>
	  key will select the left contents and the <keycap>r</keycap>
	  key will select contents from your right.  The final output
	  will be a file consisting of both parts, which can then be
	  installed.  This option is customarily used for files where
	  settings have been modified by the user.</para>

	<para>Choosing to view the &man.diff.1; results again will
	  show you the file differences just like &man.mergemaster.8;
	  did before prompting you for an option.</para>

	<para>After &man.mergemaster.8; is done with the system files
	  you will be prompted for other options.  &man.mergemaster.8;
	  may ask if you want to rebuild the password file and will
	  finish up with an option to remove left-over temporary
	  files.</para>
      </sect3>

      <sect3>
	<title>Manual Update</title>

	<para>If you wish to do the update manually, however, you
	  cannot just copy over the files from
	  <filename>/usr/src/etc</filename> to
	  <filename>/etc</filename> and have it work.  Some of these
	  files must be <quote>installed</quote> first.  This is
	  because the <filename>/usr/src/etc</filename> directory
	  <emphasis>is not</emphasis> a copy of what your
	  <filename>/etc</filename> directory should look like.  In
	  addition, there are files that should be in
	  <filename>/etc</filename> that are not in
	  <filename>/usr/src/etc</filename>.</para>

	<para>If you are using &man.mergemaster.8; (as recommended),
	  you can skip forward to the
	  <link linkend="updating-upgrading-rebooting">next
	    section</link>.</para>

	<para>The simplest way to do this by hand is to install the
	  files into a new directory, and then work through them
	  looking for differences.</para>

	<warning>
	  <title>Backup Your Existing
	    <filename>/etc</filename></title>

	  <para>Although, in theory, nothing is going to touch this
	    directory automatically, it is always better to be sure.
	    So copy your existing <filename>/etc</filename> directory
	    somewhere safe.  Something like:</para>

	  <screen>&prompt.root; <userinput>cp -Rp /etc /etc.old</userinput></screen>

	  <para><option>-R</option> does a recursive copy,
	    <option>-p</option> preserves times, ownerships on files
	    and suchlike.</para>
	</warning>

	<para>You need to build a dummy set of directories to install
	  the new <filename>/etc</filename> and other files into.
	  <filename>/var/tmp/root</filename> is a reasonable choice,
	  and there are a number of subdirectories required under this
	  as well.</para>

	<screen>&prompt.root; <userinput>mkdir /var/tmp/root</userinput>
&prompt.root; <userinput>cd /usr/src/etc</userinput>
&prompt.root; <userinput>make DESTDIR=/var/tmp/root distrib-dirs distribution</userinput></screen>

	<para>This will build the necessary directory structure and
	  install the files.  A lot of the subdirectories that have
	  been created under <filename>/var/tmp/root</filename> are
	  empty and should be deleted.  The simplest way to do this is
	  to:</para>

	<screen>&prompt.root; <userinput>cd /var/tmp/root</userinput>
&prompt.root; <userinput>find -d . -type d | xargs rmdir 2&gt;/dev/null</userinput></screen>

	<para>This will remove all empty directories.  (Standard error
	  is redirected to <filename>/dev/null</filename> to prevent
	  the warnings about the directories that are not
	  empty.)</para>

	<para><filename>/var/tmp/root</filename> now contains all the
	  files that should be placed in appropriate locations below
	  <filename>/</filename>.  You now have to go through each of
	  these files, determining how they differ with your existing
	  files.</para>

	<para>Note that some of the files that will have been
	  installed in <filename>/var/tmp/root</filename> have a
	  leading <quote>.</quote>. At the time of writing the only
	  files like this are shell startup files in
	  <filename>/var/tmp/root/</filename> and
	  <filename>/var/tmp/root/root/</filename>, although there may
	  be others (depending on when you are reading this).  Make
	  sure you use <command>ls -a</command> to catch them.</para>

	<para>The simplest way to do this is to use &man.diff.1; to
	  compare the two files:</para>

	<screen>&prompt.root; <userinput>diff /etc/shells /var/tmp/root/etc/shells</userinput></screen>

	<para>This will show you the differences between your
	  <filename>/etc/shells</filename> file and the new
	  <filename>/var/tmp/root/etc/shells</filename> file.  Use
	  these to decide whether to merge in changes that you have
	  made or whether to copy over your old file.</para>

	<tip>
	  <title>Name the New Root Directory
	    (<filename>/var/tmp/root</filename>) with a Time Stamp, so
	    You Can Easily Compare Differences Between
	    Versions</title>

	  <para>Frequently rebuilding the world means that you have to
	    update <filename>/etc</filename> frequently as well, which
	    can be a bit of a chore.</para>

	  <para>You can speed this process up by keeping a copy of the
	    last set of changed files that you merged into
	    <filename>/etc</filename>.  The following procedure gives
	    one idea of how to do this.</para>

	  <procedure>
	    <step>
	      <para>Make the world as normal.  When you want to update
		<filename>/etc</filename> and the other directories,
		give the target directory a name based on the current
		date.  If you were doing this on the 14th of February
		1998 you could do the following:</para>

	      <screen>&prompt.root; <userinput>mkdir /var/tmp/root-19980214</userinput>
&prompt.root; <userinput>cd /usr/src/etc</userinput>
&prompt.root; <userinput>make DESTDIR=/var/tmp/root-19980214 \
    distrib-dirs distribution</userinput></screen>
	    </step>

	    <step>
	      <para>Merge in the changes from this directory as
		outlined above.</para>

	      <para><emphasis>Do not</emphasis> remove the
		<filename>/var/tmp/root-19980214</filename> directory
		when you have finished.</para>
	    </step>

	    <step>
	      <para>When you have downloaded the latest version of the
		source and remade it, follow step 1.  This will give
		you a new directory, which might be called
		<filename>/var/tmp/root-19980221</filename> (if you
		wait a week between doing updates).</para>
	    </step>

	    <step>
	      <para>You can now see the differences that have been
		made in the intervening week using &man.diff.1; to
		create a recursive diff between the two
		directories:</para>

	      <screen>&prompt.root; <userinput>cd /var/tmp</userinput>
&prompt.root; <userinput>diff -r root-19980214 root-19980221</userinput></screen>

	      <para>Typically, this will be a much smaller set of
		differences than those between
		<filename>/var/tmp/root-19980221/etc</filename> and
		<filename>/etc</filename>.  Because the set of
		differences is smaller, it is easier to migrate those
		changes across into your <filename>/etc</filename>
		directory.</para>
	    </step>

	    <step>
	      <para>You can now remove the older of the two
		<filename>/var/tmp/root-*</filename>
		directories:</para>

	      <screen>&prompt.root; <userinput>rm -rf /var/tmp/root-19980214</userinput></screen>
	    </step>

	    <step>
	      <para>Repeat this process every time you need to merge
		in changes to <filename>/etc</filename>.</para>
	    </step>
	  </procedure>

	  <para>You can use &man.date.1; to automate the generation of
	    the directory names:</para>

	  <screen>&prompt.root; <userinput>mkdir /var/tmp/root-`date "+%Y%m%d"`</userinput></screen>
	</tip>
      </sect3>
    </sect2>

    <sect2 id="updating-upgrading-rebooting">
      <title>Rebooting</title>

      <para>You are now done.  After you have verified that everything
	appears to be in the right place you can reboot the system.  A
	simple &man.shutdown.8; should do it:</para>

      <screen>&prompt.root; <userinput>shutdown -r now</userinput></screen>
    </sect2>

    <sect2>
      <title>Finished</title>

      <para>You should now have successfully upgraded your &os;
	system.  Congratulations.</para>

      <para>If things went slightly wrong, it is easy to rebuild a
	particular piece of the system.  For example, if you
	accidentally deleted <filename>/etc/magic</filename> as part
	of the upgrade or merge of <filename>/etc</filename>, the
	&man.file.1; command will stop working.  In this case, the fix
	would be to run:</para>

      <screen>&prompt.root; <userinput>cd /usr/src/usr.bin/file</userinput>
&prompt.root; <userinput>make all install</userinput></screen>
    </sect2>

    <sect2 id="updating-questions">
      <title>Questions</title>

      <qandaset>
	<qandaentry>
	  <question>
	    <para>Do I need to re-make the world for every
	      change?</para>
	  </question>

	  <answer>
	    <para>There is no easy answer to this one, as it depends
	      on the nature of the change.  For example, if you just
	      ran <application>Subversion</application>, and it has
	      shown the following files as being updated:</para>

	    <screen><filename>src/games/cribbage/instr.c</filename>
<filename>src/games/sail/pl_main.c</filename>
<filename>src/release/sysinstall/config.c</filename>
<filename>src/release/sysinstall/media.c</filename>
<filename>src/share/mk/bsd.port.mk</filename></screen>

	    <para>it probably is not worth rebuilding the entire
	      world.  You could just go to the appropriate
	      sub-directories and <command>make all install</command>,
	      and that is about it.  But if something major changed,
	      for example <filename>src/lib/libc/stdlib</filename>
	      then you should either re-make the world, or at least
	      those parts of it that are statically linked (as well as
	      anything else you might have added that is statically
	      linked).</para>

	    <para>At the end of the day, it is your call.  You might
	      be happy re-making the world every fortnight say, and
	      let changes accumulate over that fortnight.  Or you
	      might want to re-make just those things that have
	      changed, and be confident you can spot all the
	      dependencies.</para>

	    <para>And, of course, this all depends on how often you
	      want to upgrade, and whether you are tracking
	      &os.stable; or &os.current;.</para>
	  </answer>
	</qandaentry>

	<qandaentry>
	  <question>
	    <para>My compile failed with lots of signal 11 (or other
	      signal number) errors.  What has happened?</para>
	  </question>

	  <answer>
	    <indexterm><primary>signal 11</primary></indexterm>

	    <para>This is normally indicative of hardware problems.
	      (Re)making the world is an effective way to stress test
	      your hardware, and will frequently throw up memory
	      problems.  These normally manifest themselves as the
	      compiler mysteriously dying on receipt of strange
	      signals.</para>

	    <para>A sure indicator of this is if you can restart the
	      make and it dies at a different point in the
	      process.</para>

	    <para>In this instance there is little you can do except
	      start swapping around the components in your machine to
	      determine which one is failing.</para>
	  </answer>
	</qandaentry>

	<qandaentry>
	  <question>
	    <para>Can I remove <filename>/usr/obj</filename> when I
	      have finished?</para>
	  </question>

	  <answer>
	    <para>The short answer is yes.</para>

	    <para><filename>/usr/obj</filename> contains all the
	      object files that were produced during the compilation
	      phase.  Normally, one of the first steps in the
	      <command>make buildworld</command> process is to remove
	      this directory and start afresh.  In this case, keeping
	      <filename>/usr/obj</filename> around after you have
	      finished makes little sense, and will free up a large
	      chunk of disk space (currently about 2&nbsp;GB).</para>

	    <para>However, if you know what you are doing you can have
	      <command>make buildworld</command> skip this step.  This
	      will make subsequent builds run much faster, since most
	      of the sources will not need to be recompiled.  The flip
	      side of this is that subtle dependency problems can
	      creep in, causing your build to fail in odd ways.  This
	      frequently generates noise on the &os; mailing lists,
	      when one person complains that their build has failed,
	      not realizing that it is because they have tried to cut
	      corners.</para>
	  </answer>
	</qandaentry>

	<qandaentry>
	  <question>
	    <para>Can interrupted builds be resumed?</para>
	  </question>

	  <answer>
	    <para>This depends on how far through the process you got
	      before you found a problem.</para>

	    <para><emphasis>In general</emphasis> (and this is not a
	      hard and fast rule) the
	      <command>make buildworld</command> process builds new
	      copies of essential tools (such as &man.gcc.1;, and
	      &man.make.1;) and the system libraries.  These tools and
	      libraries are then installed.  The new tools and
	      libraries are then used to rebuild themselves, and are
	      installed again.  The entire system (now including
	      regular user programs, such as &man.ls.1; or
	      &man.grep.1;) is then rebuilt with the new system
	      files.</para>

	    <para>If you are at the last stage, and you know it
	      (because you have looked through the output that you
	      were storing) then you can (fairly safely) do:</para>

	    <screen><emphasis>&hellip; fix the problem &hellip;</emphasis>
&prompt.root; <userinput>cd /usr/src</userinput>
&prompt.root; <userinput>make -DNO_CLEAN all</userinput></screen>

	    <para>This will not undo the work of the previous
	      <command>make buildworld</command>.</para>

	    <para>If you see the message:</para>

	    <screen>--------------------------------------------------------------
Building everything..
--------------------------------------------------------------</screen>

	    <para>in the <command>make buildworld</command> output
	      then it is probably fairly safe to do so.</para>

	    <para>If you do not see that message, or you are not sure,
	      then it is always better to be safe than sorry, and
	      restart the build from scratch.</para>
	  </answer>
	</qandaentry>

	<qandaentry>
	  <question>
	    <para>How can I speed up making the world?</para>
	  </question>

	  <answer>
	    <itemizedlist>
	      <listitem>
		<para>Run in single user mode.</para>
	      </listitem>

	      <listitem>
		<para>Put the <filename>/usr/src</filename> and
		  <filename>/usr/obj</filename> directories on
		  separate file systems held on separate disks.  If
		  possible, put these disks on separate disk
		  controllers.</para>
	      </listitem>

	      <listitem>
		<para>Better still, put these file systems across
		  multiple disks using the &man.ccd.4; (concatenated
		  disk driver) device.</para>
	      </listitem>

	      <listitem>
		<para>Turn off profiling (set
		  <quote>NO_PROFILE=true</quote> in
		  <filename>/etc/make.conf</filename>).  You almost
		  certainly do not need it.</para>
	      </listitem>

	      <listitem>
		<para>Pass the
		  <option>-j<replaceable>n</replaceable></option>
		  option to &man.make.1; to run multiple processes in
		  parallel.  This usually helps regardless of whether
		  you have a single or a multi processor
		  machine.</para>
	      </listitem>

	      <listitem>
		<para>The file system holding
		  <filename>/usr/src</filename> can be mounted (or
		  remounted) with the <option>noatime</option> option.
		  This prevents the file system from recording the
		  file access time.  You probably do not need this
		  information anyway.</para>

		<screen>&prompt.root; <userinput>mount -u -o noatime /usr/src</userinput></screen>

		<warning>
		  <para>The example assumes
		    <filename>/usr/src</filename> is on its own file
		    system.  If it is not (if it is a part of
		    <filename>/usr</filename> for example) then you
		    will need to use that file system mount point, and
		    not <filename>/usr/src</filename>.</para>
		</warning>
	      </listitem>

	      <listitem>
		<para>The file system holding
		  <filename>/usr/obj</filename> can be mounted (or
		  remounted) with the <option>async</option> option.
		  This causes disk writes to happen asynchronously.
		  In other words, the write completes immediately, and
		  the data is written to the disk a few seconds later.
		  This allows writes to be clustered together, and can
		  be a dramatic performance boost.</para>

		<warning>
		  <para>Keep in mind that this option makes your file
		    system more fragile.  With this option there is an
		    increased chance that, should power fail, the file
		    system will be in an unrecoverable state when the
		    machine restarts.</para>

		  <para>If <filename>/usr/obj</filename> is the only
		    thing on this file system then it is not a
		    problem.  If you have other, valuable data on the
		    same file system then ensure your backups are
		    fresh before you enable this option.</para>
		</warning>

		<screen>&prompt.root; <userinput>mount -u -o async /usr/obj</userinput></screen>

		<warning>
		  <para>As above, if <filename>/usr/obj</filename> is
		    not on its own file system, replace it in the
		    example with the name of the appropriate mount
		    point.</para>
		</warning>
	      </listitem>
	    </itemizedlist>
	  </answer>
	</qandaentry>

	<qandaentry>
	  <question>
	    <para>What do I do if something goes wrong?</para>
	  </question>

	  <answer>
	    <para>Make absolutely sure your environment has no
	      extraneous cruft from earlier builds.  This is simple
	      enough.</para>

	    <screen>&prompt.root; <userinput>chflags -R noschg /usr/obj/usr</userinput>
&prompt.root; <userinput>rm -rf /usr/obj/usr</userinput>
&prompt.root; <userinput>cd /usr/src</userinput>
&prompt.root; <userinput>make cleandir</userinput>
&prompt.root; <userinput>make cleandir</userinput></screen>

	    <para>Yes, <command>make cleandir</command> really should
	      be run twice.</para>

	    <para>Then restart the whole process, starting
	      with <command>make buildworld</command>.</para>

	    <para>If you still have problems, send the error and the
	      output of <command>uname -a</command> to &a.questions;.
	      Be prepared to answer other questions about your
	      setup!</para>
	  </answer>
	</qandaentry>
      </qandaset>
    </sect2>
  </sect1>

  <sect1 id="make-delete-old">
    <sect1info>
      <authorgroup>
	<author>
	  <firstname>Anton</firstname>
	  <surname>Shterenlikht</surname>
	  <contrib>Based on notes provided by </contrib>
	</author>
      </authorgroup>
    </sect1info>
    <title>Deleting Obsolete Files, Directories and Libraries</title>

    <indexterm>
      <primary>Deleting obsolete files, directories and
	libraries</primary>
    </indexterm>

    <para>As a part of the &os; development lifecycle, it happens from
      time to time that files and their contents become obsolete.
      This may be because their functionality is implemented
      elsewhere, the version number of the library has changed or it
      was removed from the system entirely.  This includes old files,
      libraries and directories, which should be removed when updating
      the system.  The benefit for the user is that the system is not
      cluttered with old files which take up unnecessary space on the
      storage (and backup) medium.  Additionally, if the old library
      had a security or stability issue, you should update to the
      newer library to keep your system safe and prevent crashes
      caused by the old library implementation.  The files,
      directories, and libraries that are considered obsolete are
      listed in <filename>/usr/src/ObsoleteFiles.inc</filename>.  The
      following instructions will help you removing these obsolete
      files during the system upgrade process.</para>

    <para>We assume you are following the steps outlined in
      <xref linkend="canonical-build"/>.  After the
      <command>make <maketarget>installworld</maketarget></command>
      and the subsequent <command>mergemaster</command> commands have
      finished successfully, you should check for obsolete files and
      libraries as follows:</para>

    <screen>&prompt.root; <userinput>cd /usr/src</userinput>
&prompt.root; <userinput>make check-old</userinput></screen>

    <para>If any obsolete files are found, they can be deleted using
      the following commands:</para>

    <screen>&prompt.root; <userinput>make delete-old</userinput></screen>

    <tip>
      <para>See <filename>/usr/src/Makefile</filename>
	for more targets of interest.</para>
    </tip>

    <para>A prompt is displayed before deleting each obsolete file.
      You can skip the prompt and let the system remove these files
      automatically by using the
      <makevar>BATCH_DELETE_OLD_FILES</makevar> make-variable as
      follows:</para>

    <screen>&prompt.root; <userinput>make -DBATCH_DELETE_OLD_FILES delete-old</userinput></screen>

    <para>You can also achieve the same goal by piping these commands
      through <command>yes</command> like this:</para>

    <screen>&prompt.root; <userinput>yes|make delete-old</userinput></screen>

    <warning>
      <title>Warning</title>

      <para>Deleting obsolete files will break applications that
	still depend on those obsolete files.  This is especially true
	for old libraries.  In most cases, you need to recompile the
	programs, ports, or libraries that used the old library before
	<command>make
	  <maketarget>delete-old-libs</maketarget></command> is
	executed.</para>
    </warning>

    <para>Utilities for checking shared library dependencies are
      available from the Ports Collection in
      <filename role="package">sysutils/libchk</filename> or <filename
	role="package">sysutils/bsdadminscripts</filename>.</para>

    <para>Obsolete shared libraries can conflict with newer libraries,
      causing messages like these:</para>

    <screen>/usr/bin/ld: warning: libz.so.4, needed by /usr/local/lib/libtiff.so, may conflict with libz.so.5
/usr/bin/ld: warning: librpcsvc.so.4, needed by /usr/local/lib/libXext.so, may conflict with librpcsvc.so.5</screen>

    <para>To solve these problems, determine which port installed the
      library:</para>

    <screen>&prompt.root; <userinput>pkg_info -W  /usr/local/lib/libtiff.so</userinput>
/usr/local/lib/libtiff.so was installed by package tiff-3.9.4
&prompt.root; <userinput>pkg_info -W /usr/local/lib/libXext.so</userinput>
/usr/local/lib/libXext.so was installed by package libXext-1.1.1,1</screen>

    <para>Then deinstall, rebuild and reinstall the port.  The
      <filename role="package">ports-mgmt/portmaster</filename> and
      <filename role="package">ports-mgmt/portupgrade</filename>
      utilities can be used to automate this process.  After you have
      made sure that all ports are rebuilt and do not use the old
      libraries any more, you can delete them using the following
      command:</para>

    <screen>&prompt.root; <userinput>make delete-old-libs</userinput></screen>
  </sect1>

  <sect1 id="small-lan">
    <sect1info>
      <authorgroup>
	<author>
	  <firstname>Mike</firstname>
	  <surname>Meyer</surname>
	  <contrib>Contributed by </contrib>
	</author>
      </authorgroup>
    </sect1info>

    <title>Tracking for Multiple Machines</title>

    <indexterm>
      <primary>NFS</primary>
      <secondary>installing multiple machines</secondary>
    </indexterm>

    <para>If you have multiple machines that you want to track the
      same source tree, then having all of them download sources and
      rebuild everything seems like a waste of resources: disk space,
      network bandwidth, and CPU cycles.  It is, and the solution is
      to have one machine do most of the work, while the rest of the
      machines mount that work via NFS.  This section outlines a
      method of doing so.</para>

    <sect2 id="small-lan-preliminaries">
      <title>Preliminaries</title>

      <para>First, identify a set of machines that is going to run
	the same set of binaries, which we will call a
	<emphasis>build set</emphasis>.  Each machine can have a
	custom kernel, but they will be running the same userland
	binaries.  From that set, choose a machine to be the
	<emphasis>build machine</emphasis>.  It is going to be the
	machine that the world and kernel are built on.  Ideally, it
	should be a fast machine that has sufficient spare CPU to run
	<command>make buildworld</command> and
	<command>make buildkernel</command>.  You will also want to
	choose a machine to be the <emphasis>test machine</emphasis>,
	which will test software updates before they are put into
	production.  This <emphasis>must</emphasis> be a machine that
	you can afford to have down for an extended period of time.
	It can be the build machine, but need not be.</para>

      <para>All the machines in this build set need to mount
	<filename>/usr/obj</filename> and
	<filename>/usr/src</filename> from the same machine, and at
	the same point.  Ideally, those are on two different drives on
	the build machine, but they can be NFS mounted on that machine
	as well.  If you have multiple build sets,
	<filename>/usr/src</filename> should be on one build machine,
	and NFS mounted on the rest.</para>

      <para>Finally make sure that
	<filename>/etc/make.conf</filename> and
	<filename>/etc/src.conf</filename> on all the machines in the
	build set agrees with the build machine.  That means that the
	build machine must build all the parts of the base system that
	any machine in the build set is going to install.  Also, each
	build machine should have its kernel name set with
	<makevar>KERNCONF</makevar> in
	<filename>/etc/make.conf</filename>, and the build machine
	should list them all in <makevar>KERNCONF</makevar>, listing
	its own kernel first.  The build machine must have the kernel
	configuration files for each machine in
	<filename>/usr/src/sys/<replaceable>arch</replaceable>/conf</filename>
	if it is going to build their kernels.</para>
    </sect2>

    <sect2 id="small-lan-base-system">
      <title>The Base System</title>

      <para>Now that all that is done, you are ready to build
	everything.  Build the kernel and world as described in
	<xref linkend="make-buildworld"/> on the build machine, but do
	not install anything.  After the build has finished, go to the
	test machine, and install the kernel you just built.  If this
	machine mounts <filename>/usr/src</filename> and
	<filename>/usr/obj</filename> via NFS, when you reboot to
	single user you will need to enable the network and mount
	them.  The easiest way to do this is to boot to multi-user,
	then run <command>shutdown now</command> to go to single user
	mode.  Once there, you can install the new kernel and world
	and run <command>mergemaster</command> just as you normally
	would.  When done, reboot to return to normal multi-user
	operations for this machine.</para>

      <para>After you are certain that everything on the test
	machine is working properly, use the same procedure to
	install the new software on each of the other machines in
	the build set.</para>
    </sect2>

    <sect2 id="small-lan-ports">
      <title>Ports</title>

      <para>The same ideas can be used for the ports tree.  The first
	critical step is mounting <filename>/usr/ports</filename> from
	the same machine to all the machines in the build set.  You
	can then set up <filename>/etc/make.conf</filename> properly
	to share distfiles.  You should set <makevar>DISTDIR</makevar>
	to a common shared directory that is writable by whichever
	user <username>root</username> is mapped to by your NFS
	mounts.  Each machine should set
	<makevar>WRKDIRPREFIX</makevar> to a local build directory.
	Finally, if you are going to be building and distributing
	packages, you should set <makevar>PACKAGES</makevar> to a
	directory similar to <makevar>DISTDIR</makevar>.</para>
    </sect2>
  </sect1>
</chapter>