Post date: Jan 25, 2011 3:51:21 PM
In March 2007, I wrote about this technique I invented for tracking the kernel configurations on the servers we use to run MailerMailer. I recently nuked that old blog but I thought it would be useful to keep this information archived, so I’m recreating and updating it now.
I keep track of my kernel configurations in Subversion. I have a common component which applies to all systems under my control, and an architecture specific component that applies separately to i386 and amd64 systems.
In the common file I include all of the required kernel configuration lines, and devices which are on all systems, such as SCSI disks, our common Ethernet controllers (we have limited vendors, so there are only a handful of drivers needed), and any other options lines we need for every system. I also include a small set of modules to build for features or devices that are present on some servers, or that are rarely used, such as the floppy disk, CD-ROM, and USB serial adapters. This speeds up builds since we don’t spend time making modules which will never be used, and keeps the kernel smaller and faster by not probing for such devices.
In the architecture-specific files are just the devices applicable to
that architecture. For example, the
pmtimer devices don’t exist for
amd64, so it is in the
i386 config file.
In each configuration file, I take advantage of the fact that the file can have ‘makeoptions’ which are basically dumped right into the generated Makefile.
So in my common file, KCICOMMON, I have this at the top:
makeoptions KCICOMMONREV="\$Revision: 2493 \$"
and in the i386 specific file, KCI32, I have this:
makeoptions KCIREV="\$Revision: 358 \$"
Since some of my systems are SMP enabled, I have a minor variant called
KCI32SMP also, which is entirely this:
What happens is that the lines inserted into the Makefile are evaluated at build-time, and those variables are made visible to the line that computes the kernel identifier string (also in the generated Makefile). One of the final steps in building the kernel is to copy the identifier string into the compiled kernel.
The final step is to automatically select the proper kernel when I run
make installkernel in the source tree. Add this line into
Now, my kernel identifies itself with uname:
% uname -i
So I know this is a 32-bit system running SMP with the version 358 i386 config and the version 2493 common configuration. A trivial look-up in subversion tells me exactly what’s in it. I can also quickly find my systems which are running kernels with older configurations on the rare occasion it is updated.
Over the last four years of using this scheme, the architecture-specific files have not been updated once. The common file has been updated several times, mostly for updating from FreeBSD 6 to 7 to 8, but also occasionally to add another module or two for features we decided to start using, such as ZFS. Also with recent versions of FreeBSD, the SMP kernel will boot and run just fine on single-processor systems, so that extra set of SMP configuration files I use will probably go away at some point, and every kernel will be SMP capable.
Remember to set the
svn:keywords property in subversion to enable the
“Revision” keyword on these files, else you’ll be stuck with the same
revision numbers forever.