[pkg-nvidia-devel] Moving diversions between packages

Russ Allbery rra at debian.org
Thu Jul 22 13:47:34 UTC 2010

Hello everyone,

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
installing libgl1-nvidia.

So, the question is: what should we do about this?  I think we have the
following options:

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 (rra at debian.org)               <http://www.eyrie.org/~eagle/>

More information about the Pkg-nvidia-devel mailing list