Fixing a FreeBSD server with out of sync etcupdate status


A system with a clean /etc is a warm and welcoming system

November 2022.
The FreeBSD logoA stock image showing an upgrade button

Introduction

Let's say you have a FreeBSD server which you upgraded multiple times, but the last time you forgot to run the etcupdate migrations.

Reference system:

FreeBSD example.net 13.1-RELEASE-p2 FreeBSD 13.1-RELEASE-p2 752f813d6 GENERIC  amd64

You can run etcupdate, but it's too late:

etcupdate extract
etcupdate

etcupdate will only update the change for the current version now.

etcupdate diff

The diff command shows a lot a changes from the previous version.

The FreeBSD manuals warns about how to use etcupdate

Fixing the previous version

You can fix your system by patching files using the diff output and the current files in /var/db/etcupdate/current, but this is time consuming and error prone.

Instead, let's fix it properly.

First, we need to identify what was the version we missed the update from.

Let's say we went from 13.0-RELEASE to 13.1-RELEASE.

We need the source tree of the previous version:

fetch http://ftp.fr.freebsd.org/pub/FreeBSD/releases/amd64/13.0-RELEASE/src.txz -o src-13.0.txz

Extract it somewhere:

mkdir /usr/src.13.0/
tar --unlink -xvpJf src-13.0.txz -C /usr/src.13.0/ --strip-components=2

Build a etcupdate tarball for that specific version

etcupdate build -s /usr/src.13.0/ etcupdate-13.0.tgz

Now, clear the etcupdate database and extract the specific tarball we just built:

rm -r /var/db/etcupdate/*
etcupdate extract -t etcupdate-13.0.tgz

Now we can run the updates from the old version:

etcupdate -p
etcupdate
etcupdate resolve

Running the update from the current version

Get the current updates from the current source tree:

etcupdate extract

If you don't have the current source tree, you can build the update database the same way we did the previous version.

Run etcupdate as usual

etcupdate -p
etcupdate
etcupdate resolve

Check that the diff now only shows local changes

etcupdate diff

All good!