Migrating to FreeBSD 10

Since FreeBSD 10 has a number of new features that will affect my FreeBSD setup, that is:

I decided to jump on the alpha release bandwagon to see what changes I would need to make. I downloaded the i386 version of the FreeBSD-10 ALPHA4 release iso and burnt to CD. I planned to install FreeBSD 10 over the backup version of FreeBSD on crimson, known as chrome. Chrome was installed in a 30GB slice (in a number of partitions) on the fourth disk drive on crimson. I figured I could just re-use these existing partitions for FreeBSD 10.

The first problem I encountered was the message:

  extracting base.tgz: can't unlink already existing object

during the extraction of the release sets to the hard disk. Googling led me to believe this might be due to insufficient disk space on the root partition, despite it being 1GB in size. I deleted the slice and re-created all the partitions (in an MBR) but with a 2GB root partition. The install then proceeded without issues. Later, I wondered if the problem was caused by the fact I originally re-installed using the existing root partition, which still had the 9.2 files on it. Hmmm, I may never know.

On reboot, the grub 1.5 boot commands could not boot the FreeBSD 10 kernel. The grub commands that worked with 9.2 were:

  root (hd3,0,a)
  kernel /boot/loader

but now this gave the error:

  Error 17 : Cannot mount selected partition

I also noticed grub complained about the partition type of (hd3,0), saying:

  Filesystem type unknown, partition type 0xa5

With a 9.2 partition, it had no problem in detecting the type. To workaround this, I used the chainloader technique:

  root (hd3,0)
  makeactive 
  chainloader +1

and chrome booted successfully.

Ports Management

Now that I had a working FreeBSD 10 OS running, the next step was to start installing the ports I needed. First, I installed the ports tree, using portsnap:

  portsnap fetch && portsnap extract

I then built the new package manager, pkg, from /usr/ports/ports-mgmt/pkg and then setup the configuration file /usr/local/etc/pkg.conf:

  # System-wide configuration file for pkg(1)
  # For more information on the file format and
  # options please refer to the pkg.conf(5) man page

  # Configuration options
  PACKAGESITE         : http://pkg.freebsd.org/${ABI}/latest
  #PKG_DBDIR          : /var/db/pkg
  #PKG_CACHEDIR       : /var/cache/pkg
  #PORTSDIR           : /usr/ports
  #PUBKEY             : /etc/ssl/pkg.conf
  #HANDLE_RC_SCRIPTS  : NO
  #PKG_MULTIREPOS     : NO
  #ASSUME_ALWAYS_YES  : NO
  #SYSLOG             : YES
  #SHLIBS             : NO
  #AUTODEPS           : NO
  PORTAUDIT_SITE      : http://portaudit.FreeBSD.org/auditfile.tbz
  #PKG_PLUGINS_DIR    : /usr/local/lib/pkg/plugins
  #PKG_ENABLE_PLUGINS : YES
  #PLUGINS            : [commands/mystat]
  #REPO_AUTOUPDATE    : YES

  # Repository definitions
  #repos:
  #  default : http://example.org/pkgng/
  #  repo1 : http://somewhere.org/pkgng/repo1/
  #  repo2 : http://somewhere.org/pkgng/repo2/

At the time of writing, the only package contained in the PACKAGESITE location is pkg itself. The population of packages has been delayed by the earlier compromise of the FreeBSD ports building cluster. So, I have to build from ports for the time being.

Update: 22nd January, 2014

Now that FreeBSD 10 has been released, the recommendation is not to bother setting up a pkg.conf file if you have no modifications to make. The desired repository is defined in a file located in /usr/local/etc/pkg/repos/FreeBSD.conf (there can be many repository configuration files in the repos directory) with the following content:

  FreeBSD: {
    url: "pkg+http://pkg.FreeBSD.org/${ABI}/latest",
    mirror_type: "srv",
    enabled: yes
  }

In addition to the latest repository, there are (according to this post from phoenix) a couple of alternatives:

  http://pkg.freebsd.org/${ABI}/release/0/ # Packages at time of release; this will not change.
  http://pkg.freebsd.org/${ABI}/quarterly/ # This is updated 3x per year.
  http://pkg.freebsd.org/${ABI}/latest/    # This is the default and updated every 2 weeks, I believe.

Emacs

I tried to build emacs (without X11, that is emacs-nox11), but that failed with:

  if test "no" = "yes"; then \
  rm -f bootstrap-emacs; \
  ln temacs bootstrap-emacs; \
  else \
  `/bin/pwd`/temacs --batch --load loadup bootstrap || exit 1; \
  test "X" = X ||  -zex emacs; \
  mv -f emacs bootstrap-emacs; \
  fi
  Loading loadup.el (source)...
  Using load-path (/usr/ports/editors/emacs-nox11/work/emacs-24.3/lisp \
   /usr/ports/editors/emacs-nox11/work/emacs-24.3/lisp/emacs-lisp \
   /usr/ports/editors/emacs-nox11/work/emacs-24.3/lisp/language \
   /usr/ports/editors/emacs-nox11/work/emacs-24.3/lisp/international \
   /usr/ports/editors/emacs-nox11/work/emacs-24.3/lisp/textmodes)
  Loading emacs-lisp/byte-run...
  Loading emacs-lisp/backquote...
  Loading subr...
  Loading version...
  Segmentation fault (core dumped)
  gmake[2]: *** [bootstrap-emacs] Error 1
  gmake[2]: Leaving directory `/usr/ports/editors/emacs-nox11/work/emacs-24.3/src'
  gmake[1]: *** [src] Error 2
  gmake[1]: Leaving directory `/usr/ports/editors/emacs-nox11/work/emacs-24.3'
  ===> Compilation failed unexpectedly.
  Try to set MAKE_JOBS_UNSAFE=yes and rebuild before reporting the failure to
  the maintainer.
  *** Error code 1

  Stop.
  make: stopped in /usr/ports/editors/emacs-nox11

Setting MAKE_JOBS_UNSAFE=yes didn't make any difference. Hmm, can't find any help via google. Maybe emacs isn't ready for CLANG yet? I set CFLAGS=-g to find out more info from the seg fault, but suprisingly I got this:

  cc -nostdlib -Demacs -I. -I/usr/ports/editors/emacs-nox11/work/emacs-24.3/src
    -I../lib -I/usr/ports/editors/emacs-nox11/work/emacs-24.3/src/../lib \
    -MMD -MF deps/.d -MP     -g -march=pentiumpro   -L/usr/local/lib \
    -Wl,-rpath=/usr/lib:/usr/local/lib -Wl,-znocombreloc \
    -o temacs pre-crt0.o /usr/lib/crt1.o /usr/lib/crti.o dispnew.o frame.o \
    scroll.o xdisp.o menu.o  window.o charset.o coding.o category.o ccl.o \
    character.o chartab.o bidi.o cm.o term.o terminal.o xfaces.o    emacs.o \
    keyboard.o macros.o keymap.o sysdep.o buffer.o filelock.o insdel.o \
    marker.o minibuf.o fileio.o dired.o cmds.o casetab.o casefiddle.o \
    indent.o search.o regex.o undo.o alloc.o data.o doc.o editfns.o \
    callint.o eval.o floatfns.o fns.o font.o print.o lread.o syntax.o \
    unexelf.o bytecode.o process.o gnutls.o callproc.o region-cache.o \
    sound.o atimer.o doprnt.o intervals.o textprop.o composite.o xml.o \
    profiler.o         terminfo.o lastfile.o gmalloc.o   vm-limit.o   \
    ../lib/libgnu.a            -lrt  -lexecinfo    \
    -lutil -lncurses         -lpthread   -lm -lgcc -lc -lgcc /usr/lib/crtn.o
  xdisp.o: In function `get_next_display_element':
  /usr/ports/editors/emacs-nox11/work/emacs-24.3/src/xdisp.c:6887: 
  undefined reference to `face_for_font'
  cc: error: linker command failed with exit code 1 (use -v to see invocation)
  gmake[2]: *** [temacs] Error 1
  gmake[2]: Leaving directory `/usr/ports/editors/emacs-nox11/work/emacs-24.3/src'
  gmake[1]: *** [src] Error 2
  gmake[1]: Leaving directory `/usr/ports/editors/emacs-nox11/work/emacs-24.3'
  ===> Compilation failed unexpectedly.
  Try to set MAKE_JOBS_UNSAFE=yes and rebuild before reporting the failure to
  the maintainer.
  *** Error code 1

Ah, now Google was helpful. This had been reported recently here and fixed in trunk revision 114482. The fix (having looked at the source to xdisp.c was quite simple. Here's the diff:

  # diff /home/mark/dev/emacs-24.3/src/xdisp.c work/emacs-24.3/src/xdisp.c
  6872c6872
  < #ifdef HAVE_WINDOW_SYSTEM
  ---
  >
  6913c6913
  < #endif /* HAVE_WINDOW_SYSTEM */
  ---

I modified the source of src/xdisp.c so that it #ifdef'd out the call to face_for_font and started make again. This time the emacs build succeeded. Why did specifying the debug flag in CFLAGS cause the link failure? I suspect that my default CFLAGS setting of "-O -pipe" caused CLANG to optimise out the call to face_for_font, but also the original segmentation fault through over-agressive optimisation. Well, it's a conjecture.

Update: 31st January, 2014

The fix for the emacs-nox11 problem described above was to make emacs-nox11 dependent on gcc4.6, rather than building with CLANG. Trouble is, that means an additional 14 packages need to be installed. Worse, if you go with the emacs24 package, it is 124 packages (all that X stuff). Given this, I decided to build and install emacs using the same approach I had used on Mac OS X, that is, from the emacs trunk source code. This only requires two additional packages, autoconf and automake.

Samba36

Building smaba36 from ports threw up another error, this time in sysutils/libsunacl. Luckily, this had also been reported.. Commenting out the check for NO_PROFILE in the Makefile was sufficient for the libsunacl port install to succeed.

DNS Support

Once I started digging into the capabilities of unbound, I realised it would not be able to be a replacement for BIND. I use BIND to:

  1. Act as local resolver and forwarder (unbound does this)
  2. Provide internal hydrus.org.uk domain name resolution (unbound does offer some of this, but doesn't support CNAME, which I use)
  3. Allow local DNS updates from a DHCP server (unbound doesn't support this)

Based on this, I installed bind99 from ports. However, the port does not come with the configuration files that were part of base, so the the existing named configuration files from FreeBSD 9.2 were reused. For reference, from /etc/namedb, these are:

  dynamic/             named.root           chrome.named.conf
  master/              rndc.key             chrome.named.options
  named.conf           slave/               working/

I copied the chroot directories and files (from under /var/namedb on a 9.2 system) to the same place on the 10 system.

A link must be created:

  ln -s /var/named/etc/namedb /etc/namedb

which makes the links created in /usr/local/etc by the port install process valid:

  lrwxr-xr-x  1 root   wheel     22  5 Oct 11:22 /usr/local/etc/named.conf@ -> /etc/namedb/named.conf
  lrwxr-xr-x  1 root   wheel     20  5 Oct 11:22 /usr/local/etc/rndc.key@ -> /etc/namedb/rndc.key

In addition, the port doesn't seem to come with any start scripts in /usr/local/etc/rc.d, so I copied the version in /etc/rc.d/named, which is still available in FreeBSD 10. I removed the check for an update of the chroot structure, as now it is my responsibility.

Finally, the /etc/rc.conf file must be updated to reference the named port binary:

  named_enable="YES"
  named_program="/usr/local/sbin/named"

This all enables bind to start exactly as in pre-FreeBSD 10, with the arguments "-t /var/named -u bind". However, I wonder if, at some point, the bind user will have to be defined locally if that is also removed from base.

Update: 11th January, 2014

The above situation for the bind ports has changed since it was written (discovered while setting up a new machine with FreeBSD 10). The bind99 port now installs configuration files and a startup script in /usr/local/etc. This is presumably due to the efforts of Erwin Lansing (based on posts to the freebsd-stable mailing list. The chroot setup has gone, but in my environment, that is not much of a concern.

So, taking the path of least resistance (or is it the road to hell?), I modiifed the bind configuration files in /usr/local/etc/namedb as required for the local network and made the following additions to /etc/rc.conf:

  named_enable="YES"
  named_program="/usr/local/sbin/named"
  named_conf="/usr/local/etc/namedb/named.conf"
  named_chrootdir=""

Also remember to remove the now redundant /etc/rc.d/named script; if you don't, named will be started twice.

FreeBSD source updates

From FreeBSD 9.1, subversion replaced cvs as the method of source code control and therefore for obtaining the FreeBSD source code. For FreeBSD 9.1 and 9.2 I installed the full subversion package. I read on the freebsd-stable mailing list that a lightweight subversion client had been developed and was available in ports. However, on installing FreeBSD 10, I discovered another svn client (svnlite) that was offered by the base system. This operates exactly as the real svn client, so a complete copy of the FreeBSD 10 source tree (currently in head) is downloaded via:

  svnlite co svn://svn.freebsd.org/base/head /usr/src

When FreeBSD 10 is baselined, I'll have to switch the checkout to releng/10.0, rather than head