Hack 79 Safely Merge Changes to /etc
Use a three-way merge to deal with upgraded configuration files.
Even though you probably run cvsup on a daily basis, you likely run make world only a few times a year, whenever a new version of the OS is released. The steps required to upgrade your system are well documented and fairly straightforward. That is, it's easy until it's time to run mergemaster.
mergemaster is an important step, as it integrates changes to /etc. For example, occasionally a core utility such as Sendmail will require a new user or group in /etc/passwd. Problems can occur if those changes aren't integrated.
If you've used mergemaster before, you know it's not the most user-friendly utility out there. Misinterpret a diff, and you might lose your configuration file changes or, worse, miss a necessary change. You might even end up blowing away your own users in /etc/passwd not the most convenient way to start off a new upgrade.
8.4.1 Initial Preparations
An alternative is to use etcmerge (/usr/ports/sysutils/etcmerge). This utility does most of the work for you. Unlike the two-way diff used by mergemaster, this utility can compare the changes between three sets of edits:
Once you've installed etcmerge, ensure you have a backup copy of /etc:
# tar czvf etc.tgz /etc
Here, I've saved a copy only to the local hard drive. Be sure to copy it to another location as well, just to be safe: to another system, a removable media, or even your email account.
The next step is to locate a copy of /etc that is original to your current operating system and save it to /var/db/etc. (This is a good step to add to your regime when you install a new system.) Assuming this isn't a fresh install and you've made changes to /etc, you can get the original, unmodified /etc for your operating system version at http://people.freebsd.org/~eivind/etc/.
Here, I've downloaded the 5.1-RELEASE version and untarred it to the correct place:
# tar -C /var/db -zxvpf etc-5.1-RELEASE.tar.gz # ls /var/db/etc/
So, now you have a copy of the original /etc, as well as your own customized /etc. You'll receive the /etc for a newer version of FreeBSD once you've changed your cvs-supfile to reflect the newer tag [Hack #80] .
For example, I'm currently running 5.1-RELEASE, so my custom supfile contains this line:
When I'm ready to upgrade to 5.2, I'll change that line to reflect the new tag:
My next cvsup will grab the sources for the new operating system version.
Once cvsup has finished downloading all of the changes, take the time to read /usr/src/UPDATING, which lists all of the known gotchas for this release. For example, there may be mandatory options for the kernel process of the upgrade, certain stages may require a reboot before the next stage works, or perhaps directory structures such as /etc have seen major changes.
Once you've made your necessary preparations, ensure these steps have succeeded before using etcmerge:
8.4.2 Using etcmerge
Now that you have a new world, use etcmerge to integrate any changes to /etc. As per its manpage, start with the initialization step:
# etcmerge init
The script will perk along for a moment or two before producing a screen full of lines that start with ETCMERGE. Here's the beginning of that output:
ETCMERGE: >>> Finding classes of files ETCMERGE: >>> Working from ETCMERGE: >>> Active: /etc ETCMERGE: >>> Reference: /var/db/etc ETCMERGE: >>> New: /root/etc-work/200401191624/etc-new
Note the name of the directory in the last line. It contains the working files that are ready for your review.
You'll then receive lines for different classes see man etcmerge for a description of each conflict class. Here's a sample output from a system I recently upgraded:
ETCMERGE: >>>> Class 7: 3 conflict(s)
A class 7 conflict means a file existed for all three versions of /etc. Any differences will appear with diff-style markers. This particular system has three files containing conflicts. Their names are in the file called 7.conflicts:
# more /root/etc-work/200401191624/7.conflicts ./manpath.config ./pwd.db ./spwd.db
The etc-merged subdirectory contains copies of those files with the differences marked. Look there and examine each file listed as containing conflicts:
# cd /root/etc-work/200401191624/etc-merged # vi manpath.config
As you review your own files, the angle bracket markers indicate which lines have changed. Next to each angle bracket marker is the name of the file containing the conflicting lines. For example, if the name of the file includes the /etc-new directory, the lines in question belong to the new version of the file. Once you've decided which version of the lines you wish to keep, remove the angle bracket lines as well as the unwanted version of the lines.
Once you're finished your edits, this command will integrate them:
# etcmerge install /etc/mail/aliases: 24 aliases, longest 10 bytes, 246 bytes total Install done - removing copies of old /etc/ and old reference. Done. #
Congratulations! You've successfully upgraded your operating system while maintaining your customizations to /etc.
8.4.3 See Also