A compilation of documentation   { en , fr }

File diversions on Debian

Created on:
Last edited on:
Xavier Béguin

The issue

When you must modify a file provided by a debian package, our version of the file will be overwrittent by default when updating the package (for files that aren't marked as "conffiles" that can be updated by the administrator).

To avoid overwriting our local changes, a diversion can be put in place to force the new version of the package to write the file to another location, thus preserving our changes to the original file.

Specific case

As an example, on a previous version of Debian testing, on systems using systemd, the bind9 package had a bug (referenced as bug #767798) that prevented the named daemon from taking into account the options provided by the administrator through variables defined in a configuration file.

Pending the correction of this bug, a simple workaround to the issue was suggested by the person that opened the bug: adding a directive to the systemd file /lib/systemd/system/bind9.service responsible for starting the named daemon to take into account the variables defined in the configuration file that was previously ignored.

However, these changes to the bind9.service file would be overwritten on each update of the bind9 package which could, in some cases, prevent named from restarting, and would make this workaround hazardous.

The solution

Installing a file diversion

The simpler solution to avoid a possible overwrite of the file was to install a diversion of the modified file until the bug was corrected in an upcoming version of the package, using the following command:

~# dpkg-divert --divert /lib/systemd/system/bind9.service.orig --rename /lib/systemd/system/bind9.service
Adding 'local diversion of /lib/systemd/system/bind9.service to /lib/systemd/system/bind9.service.orig'

Thanks to this diversion, the package writes its version of the file to /lib/systemd/system/bind9.service.orig, instead of overwriting the file /lib/systemd/system/bind9.service. (In our specific case, it's up to the system administrator updating the package to check if the new version of the file provides modifications worth applying to our own version of the file.)

Listing active file diversions

To see if a file diversion is indeed in action, the option --list of the dpkg-divert command can be used to list the diversions in place for a file. Its argument should be either the diverted file or the original file (which could take the form of a glob parttern). For example:

~# dpkg-divert --list /lib/systemd/system/bind9.service.orig
local diversion of /lib/systemd/system/bind9.service to /lib/systemd/system/bind9.service.orig

~# dpkg-divert --list /lib/systemd/system/bind9.service
local diversion of /lib/systemd/system/bind9.service to /lib/systemd/system/bind9.service.orig

~# dpkg-divert --list *bind9.service
local diversion of /lib/systemd/system/bind9.service to /lib/systemd/system/bind9.service.orig

Removing a file diversion

In our example of the bind9 package, once the bug was corrected by the package, the diversion could be removed to once again use the version of the file the package provides.

A file diversion can be removed using the --remove option with the name of the original file as argument.

In addition, either the option --rename must be used to rename the file using the diverted name to the original name (in which case the original file must not exist or the removal will fail), or the option --no-rename not to rename the file.

~# dpkg-divert --remove --rename /lib/systemd/system/bind9.service
Removing 'local diversion of /lib/systemd/system/bind9.service to /lib/systemd/system/bind9.service.orig'