Updating FreeBSD 7 (i386) to 8 (amd64)
Categories: FreeBSD, Sysadmin.
Goal
Update to the latest FreeBSD version, switch to 64 bit, and switch to full ZFS. In short, use the best I can have (or what is supposed to be the best I can have) on my computer.
Install an amd64 system
While cross compiling an amd64 system from i386 should be possible, I wanted to get sure that the nouveau video driver actually worked on amd64. I have so decided to install a fresh FreeBSD 8 on my system and perform a few tests before updating.
At that time, FreeBSD 8-BETA2 was just available, so I downloaded and installed it on a fresh partition created in place of the mysterious free space at the end of my hard disk:
# mkdir goinfre/FreeBSD # cd goinfre/FreeBSD # mkdir base kernels manpages # ftp -a ftp.freebsd.org ftp> cd /pub/FreeBSD/releases/amd64/8.0-BETA2/base ftp> lcd base ftp> mget * ftp> cd ../kernels ftp> lcd ../kernels ftp> mget * ftp> cd ../manpages ftp> lcd ../manpages ftp> mget * ftp> bye # ( cd base && DESTDIR=/goinfre sh install.sh ) # ( cd kernels && DESTDIR=/goinfre sh install.sh generic ) # mv /goinfre/boot/GENERIC /goinfre/boot/kernel # ( cd manpages && DESTDIR=/goinfre sh install.sh ) # bsdlabel -w -B -b /goinfre/boot/boot /dev/ad10s3
Since my hardware BIOS sucks when it is supposed to give up control of USB to the kernel, USB is disabled in my BIOS and I have no keyboard to choose from which slice to boot when the system starts. I have so to instruct the boot manager to boot on the third slice on next boot:
# boot0cfg -s 3 ad10
I then rebooted and setup FreeBSD 8-BETA2 networking, patched the kernel sources, checked that the nouveau video driver worked as expected, installed packages, and so on.
Setting up the disks
I basically followed instructions from the blog post Setting up a zfs-only system by Ulf Lilleengen (nanolulf), adjusting settings according to my system (4 GB swap, all available space for the ZFS partition):
# gpart delete -i 1 ad12 # gpart destroy ad12 # gpart create -s GPT ad12 # gpart add -b 34 -s 128 -t freebsd-boot ad12 # echo "4 * 1024*1024*1024 / 512" | bc 8388608 # gpart add -b 162 -s 8388608 -t freebsd-swap ad12 # gpart show ad12 => 34 625142381 ad12 GPT (298G) 34 128 1 freebsd-boot (64K) 162 8388608 2 freebsd-swap (4.0G) 8388770 616753645 - free - (294G) # gpart add -b 8388770 -s 616753645 -t freebsd-zfs ad12 # gpart bootcode -b /boot/pmbr ad12 # gpart bootcode -p /boot/gptzfsboot -i 1 ad12
Then I created the various ZFS filesystems and extracted FreeBSD 8 stable (well, still named 8.0-RC1 actually)
# zpool create data /dev/ad12p3 # zfs create data/tmp # zfs create data/usr # zfs create data/var
Installing FreeBSD 8 from sources
Since I had the right branch of the FreeBSD subversion repository checked in into the temporary FreeBSD 8 system — with local patches — I copied it to the ZFS filesystem and updated it.
# cp -R /usr/src /data/usr # cd /data/usr/src # svn up # make buildworld buildkernel # make DESTDIR=/data installworld # make DESTDIR=/data installkernel # make DESTDIR=/data distribution
I then customezed /boot/loader.conf:
cat << EOT > /data/boot/loader.conf nouveau_load=yes zfs_load=yes vfs.root.mountfrom="zfs:data" EOT
Configured the swap device:
cat << EOT > /data/etc/fstab # Device Mountpoint FStype Options Dump Pass# /dev/ad12p2 none swap sw 0 0 EOT
Customised new /etc/make.conf:
cat << EOT > /data/etc/make.conf LOADER_ZFS_SUPPORT=YES EOT
Setup the network in /etc/rc.conf:
cat << EOT > /data/etc/rc.conf # This file now contains just the overrides from /etc/defaults/rc.conf. # Please make all changes to this file, not to /etc/defaults/rc.conf. # Enable network daemons for user convenience. ifconfig_rl0="inet 192.168.63.42 netmask 255.255.255.0" defaultrouter="192.168.63.1" hostname="marvin.blogreen.org" named_enable="YES" # asterisk_enable="YES" # dbus_enable="YES" # hald_enable="YES" # gdm_enable="YES" # gdm_lang="fr_FR.UTF-8" EOT
I finally finished the ZFS setup:
# zfs export data && zfs import data # cp /boot/zfs/zpool.cache /data/boot/zfs # zfs set mountpoint=legacy data # zfs set mountpoint=/usr data/usr # zfs set mountpoint=/var data/var # zpool set bootfs=data data
I then booted the fresh install from ZFS and finished the system configuration:
# passwd # tzsetup # adduser
Mirroring data
Since I have two identical disks on my system and wanted to have some kind of redundancy for a while, I set-up the second disk as a mirror of the first one.
First, I prepared the old disk so it has the same structure as the new with the ZFS filesystem:
# gpart show ad10 => 63 625142385 ad10 MBR (298G) 63 104856192 1 freebsd (50G) 104856255 419425020 2 freebsd (200G) 524281275 100856070 3 freebsd (48G) 625137345 5103 - free - (2.5M) # gpart delete -i 1 ad10 # gpart delete -i 2 ad10 # gpart delete -i 3 ad10 # gpart destroy ad10 # gpart create -s GPT ad10 # gpart add -b 34 -s 128 -t freebsd-boot ad10 # gpart add -b 162 -s 8388608 -t freebsd-swap ad10 # gpart show ad10 => 34 625142381 ad10 GPT (298G) 34 128 1 freebsd-boot (64K) 162 8388608 2 freebsd-swap (4.0G) 8388770 616753645 - free - (294G) # gpart add -b 8388770 -s 616753645 -t freebsd-zfs ad10 # gpart bootcode -b /boot/pmbr ad10 # gpart bootcode -p /boot/gptzfsboot -i 1 ad10
I added my new 4 Gib swap to /etc/fstab and enabled it:
# echo "/dev/ad10p2 none swap sw 0 0" >> /etc/fstab # swapon /dev/ad10p2
I could then tell ZFS to mirror ad10p3 and ad12p3:
# zpool attach data ad12p3 ad10p3 # zpool status pool: data state: ONLINE status: One or more devices is currently being resilvered. The pool will continue to function, possibly in a degraded state. action: Wait for the resilver to complete. scrub: resilver in progress for 0h2m, 0.35% done, 13h33m to go config: NAME STATE READ WRITE CKSUM data ONLINE 0 0 0 mirror ONLINE 0 0 0 ad12p3 ONLINE 0 0 0 44.6M resilvered ad10p3 ONLINE 0 0 0 754M resilvered errors: No known data errors
The nice part is of course that you can continue to use the system while you are doing all this!