Keeping FreeBSD Up-to-date

Table of Contents

1. Introduction

When I started using FreeBSD back in the
2.2.2-RELEASE

days, I had little
knowledge of the tools available for keeping the system updated with
the latest versions of programs and security fixes. Most of the tools
which existed for updating FreeBSD are still in use today, along with a
number of extra applications for making them easier to use and more
comprehensive.

2. Staying Current to the Minute with CVSup

The CVSup
utility by John Polstra, is recognized as the standard for keeping system
files on a FreeBSD system up-to-date. CVSup automates the process of
connecting to a server and mirroring the files in a specific collection,
only downloading as little data as necessary to update your local files to
the versions available on the FreeBSD master CVS repository.

There are alternatives to CVSup for staying current, including anonymous
CVS and CTM, as well as ordering CD and DVD subscriptions. More information
can be found in the FreeBSD Handbook:

http://www.freebsd.org/handbook/mirrors.html

2.1. Installing CVSup

It is possible you may have already installed CVSup during installation.
To find out, try typing cvsup -v at a shell prompt. You should
get output similar to the following:

CVSup client, GUI version
Copyright 1996-2001 John D. Polstra
Software version: SNAP_16_1e
Protocol version: 17.0
Operating system: FreeBSD4
http://www.polstra.com/projects/freeware/CVSup/
Report problems to cvsup-bugs@polstra.com

If the software version is older than SNAP_16_1e, or if you don’t have
CVSup installed, then you will need to install the latest version
(older versions of CVSup have a
timestamp bug caused by
the S1G rollover).

Although you can install CVSup from the Ports Collection (covered later),
I recommend you install the statically-linked package. The non-static
version of CVSup depends on the Modula-3 libraries, which may take a long
time to build and install, and unless you’re a Modula-3 developer, you
probably won’t need them for anything else. To install the package, run
the following command (as root):

pkg_add http://people.freebsd.org/~jdp/s1g/i386-gui/cvsup-16.1e.tgz

This will fetch and install the CVSup package.

2.2. Creating cvsup files

To run CVSup, you need a "supfile", which instructs CVSup what server,
collections, and update options to use. I use a number of pre-built
CVSup files found below (you may want to change the "host" line to
a closer mirror. You can download these files to any directory you
want; common locations are /usr/local/etc, /usr/cvsup, and
/usr/local/share/cvsup.

2.2.1. Update the Ports Collection

Download ports.cvsup.

*defaulthost=cvsup3.freebsd.org
*defaultbase=/usr
*defaultprefix=/usr
*defaultrelease=cvs
*defaulttag=.
*defaultdelete use-rel-suffix

ports-all

2.2.2. Update the sources to the latest 4-STABLE

Download stable.cvsup.

*defaulthost=cvsup3.freebsd.org
*defaultbase=/usr
*defaultprefix=/usr
*defaultrelease=cvs
*defaulttag=RELENG_4
*defaultdelete use-rel-suffix

src-all

2.2.3. Update the source to the latest 5-CURRENT

Download current.cvsup.

*defaulthost=cvsup3.freebsd.org
*defaultbase=/usr
*defaultprefix=/usr
*defaultrelease=cvs
*defaulttag=.
*defaultdelete use-rel-suffix

src-all

3. About FreeBSD Ports and Packages

The FreeBSD packaging system is quite a bit different than packaging
systems for Linux distributions. "Packages" in FreeBSD are always binary,
and will usually install all development headers, libraries, and other
resources instead of using a separate "-devel" package (to confuse things
further, "-devel" packages in FreeBSD usually refer to snapshots of
packages which are under development).

The Ports Collection usually builds from source code, and allows much
greater flexibility in compile-time options (such as enabling or disabiling
different features). All packages actually originate as ports.

Everything in the package system (including ports) revolves around
the package database, which is found in the /var/db/pkg directory. Each
installed package is represented by a subdirectory, and instead the directory
are a number of text files which store data about dependencies and what
files belong to the package. This means that editing the package database
is simply a matter of adding and removing directories, and editing the
text files they contain.

Tip:
After updating your Ports Collection, you can get a list of ports which
have newer versions available with the following command:
pkg_version -l '' -v

3.1. Packages: Installing Apps

The FreeBSD package system allows you to install pre-compiled applications
via package files. FreeBSD package files end with the extension ".tgz",
which may be confusing, but accurately describe the fact that they are simply
gzipped tarballs with a few extra files for install scripts and packing
lists (among other things).

Packages can be found on the FreeBSD CDs or off the net, usually from
ftp://ftp.freebsd.org/pub/FreeBSD/packages/ (or a closer mirror).

There are two ways of installing packages: The sysinstall(1) utility, which
provides an ncurses interface to managing packages, and the command-line
utility pkg_add(1).

3.1.1. Installing via sysinstall

sysinstall(1) is the same tool which is used for installing FreeBSD,
hence the name. sysinstall can fetch package lists from many different
media sources (including CD, FTP, and NFS) and build a menu of installed
and available packages from that source.

To install packages via sysinstall, run sysinstall as root:

# /stand/sysinstall

From the menu, select "Configure", then "Packages". You should be
prompted to select a source. Once you have selected a source, sysinstall
will download the package list from that source and display a menu of
package categories. When selecting packages, if you select one package,
then all of its dependencies will automatically be selected (they will be
marked with a "D"). Packages to add will be queued until you select
"Install Packages" from the category menu.

To uninstall packages, deselect the item. The package will be uninstalled
immediately.

Note: I really only recommend that you use sysinstall when
installing packages from a CD, since it doesn’t understand changes to
package categories very well.

3.1.2. Installing via pkg_add

pkg_add(1) is actually the utility which gets called by sysinstall
when installing packages. To use it, specify a package file to install
(pkg_add understands URLs, so you can point it at a package from the
web or FTP). Example:

pkg_add mozilla-0.9.9_1,1.tgz

To uninstall a package, use pkg_delete(1). Note that you will have
to specify the version number of the package:

pkg_delete mozilla-0.9.9_1,1

To find information about a package, use pkg_info(1). Just as with
pkg_delete, you must specify the version of the package.

Tip:
To use auto-completion of package names, specify the full path to the
package, e.g., "pkg_delete /var/db/pkg/mozilla-0.9.9_1,1".

Tip:
To find out what package a file belongs to, use
"pkg_add -W filename".

3.2. Ports: Installing Apps the Easy Way

The FreeBSD Ports Collection allows greater control over the install
process, and is always more up-to-date than the packages since the official
packages all originate as ports.

The Ports Collection is usually installed in /usr/ports, and is
arranged by category. To install an application from the Ports Collection,
simply cd into the directory for that application (e.g.,
"/usr/ports/www/mozilla") and type (as root) make install.
The source code for the application will be downloaded (consulting mirrors
if necessary), checked, configured, built, and installed as if it were a
package. Any dependencies for the app will also be installed automatically,
using the Ports Collection.

Also, some ports may have special warnings, messages, or options for
building and installing (for example, the www/mod_php4 port displays a
menu allowing you to select what compile-time features of PHP to
enable).

Once a port has finished installing, typing make clean will
clean up the work files.

Since installing a port adds an entry to the package database, you can
uninstall it by using the pkg_delete(1) command.

To build your own package from a port, use make package.
The resulting package can be found in /usr/ports/packages/All, with
symlinks to it in /usr/ports/packages/Latest and in
/usr/ports/packages/(category). In fact, this is exactly the system
used by the FreeBSD master package builder to periodically generate
new packages.

3.2.1. Finding Ports

Finding what directory a port lives in can be daunting at times, due to
the large size of the Ports Collection. There are three ways to find
where a particular port lives:

  1. Use FreshPorts. FreshPorts, at http://www.freshports.org/
    is essentially the FreeBSD equivalent of
    Freshmeat.net. You can search
    for ports, view descriptions, and view changes made to the port.
  2. Use ‘whereis’. The whereis(1) command includes the ports
    directories in its search, so you can try to guess the name of the port:

    # whereis mozilla
    mozilla: /usr/ports/www/mozilla

  3. Use ‘make search’. The Ports Collection has a search feature
    built-in. Example:

    # cd /usr/ports

    # make search key=’mozilla’

When installing modules for a particular language, ports entries have
a specific naming convention to make them easier to find:

  • Perl: Perl ports are prefixed with "p5-". The "::" in module
    names is converted to a "-". For example, the popular "Date::Manip"

    module is found in /usr/ports/devel/p5-Date-Manip.

  • Python: Python ports are prefixed with "py-" or "py22-" (if
    the module is only usable with Python 2.2).
  • Ruby: Ruby ports are prefixed with "ruby-".

3.2.2. Setting Port Options

The file /etc/make.conf sets all global options for building ports
(as well as options for building the kernel and the world). The defaults
can be found in /etc/defaults/make.conf. Any entries in /etc/make.conf
will override the defaults. There are options for specifying options to
gcc (CPUTYPE, CFLAGS), whether to install documentation with ports
(NOPORTDOCS), what version of XFree86 to use (XFREE86_VERSION),
and export control settings (USA_RESIDENT).

Tip:
Many ports have the option of building Gnome-specific versions. By default,
if Gnome is installed, then any ports installed afterwards will be
build with Gnome options. To disable this behavior, either add
WITHOUT_GNOME=1 in /etc/make.conf or type it at the
command line before installing the port.

Tip:
If you are running XFree86 4.x (instead of the default 3.x), add
XFREE86_VERSION=4 in make.conf. Otherwise, ports which
depend on X will attempt to compile XFree86 3.x as a dependency!

3.3. Portupgrade: Installing Apps the Even Easier Way

To address the problem of how to cleanly upgrade a package or port to
the latest version, Akinori MUSHA
has created the Portupgrade suite of tools, which automate the process
of using the Ports Collection.

Installing Portupgrade is simple from the Ports Collection:

# cd /usr/ports/sysutils/portupgrade
# make install

Note that Portupgrade is written in Ruby, so the Ruby interpreter will
need to be installed (this should be done automatically when installing
from the Ports Collection).

Once installed, Portupgrade maintains its own package database which
mirrors the real database. Whenever you make changes to files within
/var/db/pkg, it automatically detects the changes and updates its internal
database.

An example of using Portupgrade to upgrade a package using the Ports
Collection:

# portupgrade mozilla

That’s it, no version number needed (it automatically figures out which
version of an installed package needs updating).

If you want to upgrade a package via a package (and not the Ports
Collection), use the "-p" option with Portupgrade. It will attempt to
fetch the package from the FreeBSD master FTP site, and failing that, will
build from the Ports Collection. (For more options about this, see the
portupgrade(1) manpage).

While you can still use pkg_add and make install
to install packages and ports (respectively), Portupgrade provides the
"portinstall" utility which has many of the same options as Portupgrade.

Portupgrade also contains a utility to check and fix the package database
if something bad happens (such as circular dependencies, multiply-installed
packages, etc.). The command "pkgdb -F" will scan the package
database, verifying that all entries make sense. It will ask you how you
want to fix any problems encountered (with a bit of logic to suggest an
appropriate solution).

3.4. A Note About Version Numbers

The version numbers used in FreeBSD packages may seem a bit odd. This
is due to the way ports are marked. For example:

mozilla-0.9.9_1,1

In this example, "0.9.9" is the version of the application itself.
The "_1" is the "portrevision". Every time a change is made to a port
which can affect the installation (such as adding a patch to fix a security
hole or fixing the list of files installed), the portrevision is bumped up
by one. When a new version of the application is released, the
portrevision is reset.

The ",1" in the version number is called the "portepoch". This value
is incremented by one every time a port is reverted to an older version due
to a major issue (such as security problems, licensing or distribution
changes). The portepoch may never decrease.

4. Upgrading to the Latest Version

4.1. Branches

The FreeBSD project develops two different major branches concurrently,
as well as many smaller branches. The two main branches are "-STABLE"
and "-CURRENT". The way releases come about is through the following
process:

  • Patches to patches are first applied to -CURRENT, usually with an
    "MFC-after" note, which specifies the length of time for testing.
    (MFC stands for "Merge From Current").
  • Eventually, most patches are merged into the -STABLE branch.
  • Periodically, on a release schedule which takes into account major
    changes in features and bundled applications, the FreeBSD core team will
    mark a particular snapshot of -STABLE as "-RELEASE".

As of this article, the current stable version of FreeBSD is
"4-STABLE" and the current development version is "5-CURRENT".

4.2. Building the New Version

First, use CVSup to update your sources to the latest version (see
section 2.2). Next, do the following steps:

# cd /usr/src
# make world
# make buildkernel KERNCONF=GENERIC
# make installkernel KERNCONF=GENERIC
# mergemaster

If you are using a custom kernel configuration, replace
"GENERIC" with the name of your kernel configuration file.

5. References