FreeBSD and beadm

One of Solaris’ ZFS features is boot environments, where you can install multiple versions of the core operating systems and choose which one to boot into. Boot environments take a lot of the risk out of upgrades; if an upgrade goes bad, you can easily roll back to the previous version.

Boot environments are built on top of ZFS. Recent FreeBSD installers create fine-grained datasets rather than a single large dataset, which means you can leverage boot environments on FreeBSD.

Boot environments will go into FreeBSD Mastery: Advanced ZFS. But the first book needs to be boot-environment compatible–especially the chapter on manual ZFS installations. So here are my rough notes on boot environments, both from my own researches and from poking Allan Jude on Twitter.

If you’re going to play with boot environments, it’s best to start with a new system. You can migrate an existing system to a boot environment friendly one, but as Dan Langille discovered, it’s a right pain.

I started by installing a new 10.1/amd64 host. Your initial datasets look like this.

# zfs list
NAME USED AVAIL REFER MOUNTPOINT
zroot 465M 188G 128K none
zroot/ROOT 463M 188G 128K none
zroot/ROOT/default 462M 188G 462M /
zroot/tmp 149K 188G 149K /tmp
zroot/usr 570K 188G 128K /usr
zroot/usr/home 186K 188G 186K /usr/home
zroot/usr/ports 128K 188G 128K /usr/ports
zroot/usr/src 128K 188G 128K /usr/src
zroot/var 703K 188G 128K /var
zroot/var/crash 128K 188G 128K /var/crash
zroot/var/log 192K 188G 192K /var/log
zroot/var/mail 128K 188G 128K /var/mail
zroot/var/tmp 128K 188G 128K /var/tmp

1
This list is deceptive. The dataset zroot/usr exists, but it isn’t mounted. Go ahead, run mount(8) or zfs mount and check. I’ll wait. The dataset must exist for you to have child datasets like /usr/ports, but it doesn’t actually contain any data. The files in /usr that aren’t in specific child datasets like /usr/ports or /usr/src are all in the root dataset.

Run pkg install once to install the package management system, and then install beadm from packages.

# pkg install
# pkg install -y beadm

Now see which boot environments you have.

# beadm list
BE Active Mountpoint Space Created
default NR / 494.0M 2015-04-08 07:18

The only boot environment is named default. Under active, N means the environment is active now. An R means the environment will be active on reboot.

I need to upgrade this host to the latest version of FreeBSD 10.1, p9. This is where we need a new boot environment. I’ll name it after the release.

# beadm create 10.1-p9
Created successfully
# beadm list
BE Active Mountpoint Space Created
default NR / 646.0M 2015-04-08 07:18
10.1-p9 - - 10.7K 2015-04-08 11:43

Activate the new boot environment.

# beadm activate 10.1-p9
Activated successfully
# beadm list
BE Active Mountpoint Space Created
default N / 186.0K 2015-04-08 07:18
10.1-p9 R - 646.2M 2015-04-08 11:43

While the default environment has an N, indicating it’s active now, the 10.1-p9 environment has an R, so it will be active after a reboot.

Reboot. After the reboot, you’ll see the new environment is running.

# beadm list
BE Active Mountpoint Space Created
default - - 538.0K 2015-04-08 07:18
10.1-p9 NR / 646.3M 2015-04-08 11:43

Now I can install the latest FreeBSD patches without damaging my default system. If it fails, I can fall back by activating the default boot environment.

Remember how the zroot/usr partition isn’t mounted, so that files on /usr fall through to the root dataset. Your files in /usr and /usr/local are in the boot environment, so you can create new boot environments for package upgrades as well as base system updates. The /var partition works similarly.

Using boot environments opens another whole crate of weasels, though. Of course you want the core system databases in /var/db to be part of the boot environment–but what about /var/db/mysql? Similarly, postgres stashes data in /usr/local/postgres. You don’t want reverting the core operating system to give you an old version of the system database!

When using boot environments, create a new dataset for your database data. This also lets you tune ZFS for that application.

(PS: While you’re here, take a moment to admire how the header image changes every 10 seconds. I am immensely proud of myself for finding the button that made that happen. That’s, like, real web design! And for changing the density of the bookshelf photo so it looked okay in the header. That makes me a graphic designer too, right? Sweet!)

2 Replies to “FreeBSD and beadm”

  1. Thanks for this! Sort of wish they hadn’t gone with “N” to represent currently active BE tho 🙂

Comments are closed.