February 28, 2008

Updating to FreeBSD 7.0

Categories: FreeBSD, Sysadmin.

I have just updated my main machine from FreeBSD-6.2-STABLE to FreeBSD-7.0-STABLE. As usual with FreeBSD, the update was smooth :-).

Here are a few hints to reduce even more your downtime: about half on hour in my case.

Prepare the update

First, you need to fetch FreeBSD's source code using csup(1) or cvsup(1). My favourite way of doing this is to configure everything one time for all in /etc/make.conf:

SUP=            /usr/bin/csup
SUPFLAGS=       -g -L 2 -1
SUP_UPDATE=     yes
SUPHOST=        cvsup.fr.FreeBSD.org
SUPFILE=        /usr/share/examples/cvsup/stable-supfile
PORTSSUPFILE=   /usr/share/examples/cvsup/ports-supfile

Updating the system source is now as simple as issuing make update in the /usr/src/ directory (if this directory does not exists, run sysinstall, select ConfigureDistributionssrcbase to install the files required for bootstrapping).

If you use a custom kernel, you will probably have to tweak your configuration a bit: a few options have been renamed (e.g. GEOM_GPTGEOM_PART_GPT, COMPAT_43COMPAT_43TTY), new options are enabled in the GENERIC kernel (e.g. SCTP, UFS_GJOURNAL, GEOM_LABEL) and you will probably want to add the COMPAT_FREEBSD6 option to your kernel and maybe switch to the new ULE scheduler replacing the SCHED_4BSD option with SCHED_ULE.

My personal recipe is to base my kernel configuration file on GENERIC, comment-out what is useless and add my custom settings at the end of the file. It is then easier to merge changes in the custom kernel configuration file using vimdiff(1) or meld.

Update the system

The update procedure is detailed in /usr/src/Makefile:

 1.  `cd /usr/src'       (or to the directory containing your source tree).
 2.  `make buildworld'
 3.  `make buildkernel KERNCONF=YOUR_KERNEL_HERE'     (default is GENERIC).
 4.  `make installkernel KERNCONF=YOUR_KERNEL_HERE'   (default is GENERIC).
      [steps 3. & 4. can be combined by using the "kernel" target]
 5.  `reboot'        (in single user mode: boot -s from the loader prompt).
 6.  `mergemaster -p'
 7.  `make installworld'
 8.  `make delete-old'
 9.  `mergemaster'
10.  `reboot'
11.  `make delete-old-libs' (in case no 3rd party program uses them anymore)

A few notes before you start:

You are now ready to cd /usr/src && make buildworld && make kernel! Reboot then in single user mode:

Enter full pathname of shell or RETURN for /bin/sh:
# mount -a
# cd /usr/src
# mergemaster -p
Do you wish to delete what is left of /var/tmp/temproot? [no] yes
# make installworld
# yes | make delete-old
# mergemaster
Do you wish to delete what is left of /var/tmp/temproot? [no] yes
# reboot

Update ports

Because the system base libraries have been updated, it is necessary to update all installed ports so that they are linked against the libraries provided by FreeBSD-7.0-STABLE instead of the deprecated ones (that will be removed later). You will so have to recompile all your installed ports.

You will NOT want to use portupgrade -fa on a production server since inconsistencies in libraries will prevent your programs from starting. As an example, consider you have two ports (say a program P and a library L.so.1), one depending on the other (P -> L.so.1) and both using pthread(3). The pthread library has been updated and binary that used to be linked against libpthread.so.2 are now linked against libthr.so.3. As a result, when portupgrade has updated the library and not updated the program yet, we have the following object dependencies:

	L.so.1 => /usr/local/lib/L.so.1
	libpthread.so.2 => /lib/libpthread.so.2
	libthr.so.3 => /lib/libthr.so.3

The program is supposed to use two versions of the same library and — of course — this is not supported, and you will have to wait that portupgrade has updated the program to use it again. This inconsistent state can be long if you have many installed ports.

If downtime is a concern, you will probably want to build packages on another machine (or in a tinderbox) and then perform the update using your packages.

Note: portupgrade(1) has been updated recently and you can experience regressions leading to the program crash. Since it is unusual (I mean not limited of the update process, and probably will not last in time), I give a few tips on how to recover from portupdate(1) crashes in another post.

Finish the update

The final step consists in removing the deprecated libraries from the base system. This may break programs that have not been recompiled so you may want to make a backup:

# cd /usr/src && make check-old-libs  | grep '^/' | tar zcv -T - -f /root/FreeBSD-7.0-old-libs.tar.gz


# yes | make delete-old-libs

No Comments Yet

Comments RSS feed | Leave a Reply…