Moving diversions between packages
We just ran into a hairy problem with diversions, and I want to get the
general advice of the project on how to handle it. (This is a reason why
there's not yet been a new upload of the non-free NVIDIA legacy drivers,
although mostly it's because I've been juggling too many balls.)
Background for those who aren't familiar with how the proprietary NVIDIA
drivers work: using the NVIDIA X driver requires both having loaded a
kernel module and replacing your libGL library used by running GL
applications. The normal libgl1-mesa will not work with the NVIDIA
driver. Currently, this is handled by having the nvidia-glx package
install the X driver, divert libGL.so.1 and install its own copy, and
depend on either the appropriate kernel module package or on the DKMS
We have a long-standing request (#369316) to allow installation of the
NVIDIA libGL library without depending on the kernel module or installing
the X driver. A common example is running GL programs from a chroot
(possibly because it's an older or newer version of Debian than the base
system or a different architecture). It doesn't make sense to install all
of nvidia-glx in the chroot because the X driver and the corresponding
kernel module dependency are only needed in the main system where the X
server is running.
We're attempting to solve this problem by splitting out just the libGL
library into a separate package (libgl1-nvidia) that can be independently
installed. However, that means the diversions of libGL have to move from
nvidia-glx to this new package. And that's where we ran into problems.
The problem is this: the new libgl1-nvidia package needs to take over the
diversions from the nvidia-glx package in its preinst so that its files
will be unpacked in the correct places. It also needs to conflict with
the old version of nvidia-glx since they're both providing the same
diversions and the same files. But the sequence of actions when
installing a new package that conflicts with another is:
old-package prerm deconfigure
old-package prerm remove
new-package preinst install
<remove old files>
old-package postrm remove
new-package postinst configure
This means that libgl1-nvidia takes over the diversions, and then the old
nvidia-glx package's postrm remove attempts to remove the diversions and
fails. Because this is removal of a conflicting package, not an upgrade
case, we can't catch the maintainer script failure and dpkg terminates the
installation with an error.
You only see this behavior when using dpkg to install the new
libgl1-nvidia package directly with dpkg. If you use a package manager
such as apt-get or aptitude, they will prefer upgrading nvidia-glx to the
new package version (which knows it doesn't own the diversions) over
removing nvidia-glx due to the conflict, and this sequence works fine.
You also of course don't see this problem if you upgrade nvidia-glx before
So, the question is: what should we do about this? I think we have the
1. Ignore the problem. apt-get and aptitude both do the right thing, so
most users are never going to see the problem. If we do take this
route (which is what is in Subversion right now), we'll have the
libgl1-nvidia preinst script exit with an error telling the user to
upgrade nvidia-glx first so that the installation fails cleanly early
on with an error.
2. Add a temporary circular dependency by making libgl1-nvidia depend on
the new version of nvidia-glx as well as conflict with the old version.
This means the package won't immediately address the problem we're
trying to solve, but it might help with this scenario. Breaking the
dependency loop by installing libgl1-nvidia first would violate both a
Depends and a Conflicts, whereas breaking the loop by upgrading
nvidia-glx first would only violate a Depends, so presumably there's
enough information there to figure out how to break the loop in the way
we want. But I don't know if dpkg would actually do that reliably, and
I'm not sure when it would then be safe to remove that dependency.
3. Stop using diversions entirely and just have libgl1-nvidia Provide and
Conflict with libgl1. I'd love to do this, since it would make the
packages much simpler, but this runs into a serious problem: this means
that nvidia-glx would effectively conflit with libgl1-mesa-dev, which
means one could not build GL packages for Debian on a system using the
proprietary drivers. Right now, we take special care to point the *.so
link at the diverted libgl1-mesa package if it is installed so that
this will work correctly. I'm an "always build in a chroot" person,
but we know that we have people who want to build Debian packages that
use GL even though the NVIDIA drivers are installed.
4. Do something else to move the diversions that I haven't thought of and
that would wonderfully solve all of our problems.
I'd love to get opinions on what we should do here. It seems like moving
diversions between packages is something that we would have run into in
the past and should have a good answer for.
In the absence of (4), I'm currently leaning towards option (1), but I
don't know if I'm missing something that makes that even less robust than
I think it is.
Russ Allbery (firstname.lastname@example.org) <http://www.eyrie.org/~eagle/>