The proper way to update FreeBSD jails between point releases

Posted by Orville Bennett on 8 October 2018
Read time: about 5 minutes

As I've mentioned before, FreeBSD has this concept of a jail which allows you to isolate an environment from the host operating system. This isolation keeps the rest of the system safe from whatever is being run inside of the jail. You can liken it to running an application in a virtual machine, but without the overhead of emulating a computer within another computer.

I thought it would be useful to document using the ezjail-admin application to update jails the right way. And, while we're at it, show how to recover from doing it the wrong way. So without further ado:

Updating jails between point releases

Run the following steps to get the jail host updated to the next point release of FreeBSD. For example, if you are on FreeBSD 11.1 and are trying to update to FreeBSD 11.2.

  1. freebsd-update fetch
  2. freebsd-update install
  3. Reboot.
  4. Repeat steps 1-3 until no more updates are available.
  5. freebsd-update upgrade -r 11.2-RELEASE
  6. Merge any configs that need to be merged.1
  7. Reboot.
  8. freebsd-update fetch
  9. freebsd-update install

Once the host machine has been updated, the next step is to update your jails. The simplest way to do this is using the ezjail-admin update -U -s $FREEBSD_VERSION command. BUT. It's very easy to mess up the upgrade by glossing over the instructions in the ezjail-admin manual.

 -U Use freebsd-update(8) to upgrade the basejail to the hosts
    operating system version, or a version you may pass freebsd-
    update's call to “uname -r” via the UNAME_r environment variable.
    Since there currently is no way of inferring the osversion
    currently installed in the basejail, you need to remember the
    original osversion and pass it to this script using the -s
    option.
 -s sourcedir | sourceosversion
    In the -b and -i case: Use the sources in sourcedir instead of
    /usr/src.  Variable: “$ezjail_sourcetree”.
    In the -U case: Pass this release tag to freebsd-update(8) as the
    source OS version of the basejail.

You might be tempted to pass the version you want to upgrade to as the parameter to -s. This would be wrong. Instead, you need to pass the version that you are upgrading from. So, if your jail is currently on FreeBSD 11.1 the command to upgrade to FreeBSD 11.2 is as follows:

ezjail-admin update -U -s 11.1-RELEASE

After finishing this update you should be able to finish upgrading the packages within your jail using these steps:

  1. ezjail-admin console $name_of_jail_here
  2. pkg upgrade
  3. Say yes to prompts as is necessary.
  4. Restart running services as necessary
    • Or, restart the entire jail via ezjail-admin restart $name_of_jail_here
  5. Verify that services are still running.

After that everything should be up to date and you'll be ready to move on to other tasks.

Recovering after updating jails between point releases incorrectly

So you screwed up. You didn't read the manual closely enough2. And instead you ran this incorrect command:

ezjail-admin update -U -s 11.2-RELEASE

Now when you try to do a pkg upgrade in your jail(s) you get a message saying you need to set some environment variable because userland and kernel are out of sync. Or when you try to build a port, your jail will think you are still on a previous version of FreeBSD and give you the following message:

Ports Collection support for your FreeBSD version has ended, and no ports are guaranteed to build on this system. Please upgrade to a supported release.

I could have solved this by using ZFS' facilities to roll back the basejail to its previous state, and then run the correct command. I was short on time however. Instead I just used the ezjail-admin install command to overwrite the existing basejail with the correct version.

ezjail-admin install -r 11.2-RELEASE

After doing that, I was able to run the following commands to update my jails:

  1. ezjail-admin console $name_of_jail_here
  2. pkg upgrade
  3. Say yes to prompts as is necessary.
  4. Restart running services as necessary
    • Or, restart the entire jail via ezjail-admin restart $name_of_jail_here
  5. Verify that services are still running.

beadm: A better way to update FreeBSD?

FreeBSD comes with ZFS support baked in and I've heard that Solaris admins use this thing called beadm to help update their ZFS systems. It's also available in FreeBSD, so next time I might try using beadm when updating. Instructions on how to update FreeBSD using beadm and freebsd-update are given in Dan Langille's Other Diary.

Have questions? Comments? @reply to @opinion8d_logic on twitter with the hashtag #therightway.

1

This is actually the tricky part in the whole thing. If you are not familiar with merging , take your time and do it carefully.

2

All credit for finding the correct solution goes to this guy on the FreeBSD forums.