[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: dpkg divert in preinst scripts



On Thu, 8 Apr 2010 17:34:58 -0500
Jonathan Nieder <jrnieder@gmail.com> wrote:

> > Conceptually, a diverting package actually pre-depends on the package
> > being diverted.
> 
> The main purpose of dpkg-divert is to tell dpkg, instead of putting
> that file here, put it there.  That is useful whether the file is
> already on the file system or not, as long as the diversion takes
> place before one of the two copies of a file is unpacked.

That doesn't mean that the two packages shouldn't conflict and replace
or be split such that the parts of the package that don't conflict get
into a new binary package.

Current behaviour of dpkg-divert is not an excuse to retain it, IMHO.
Conceptually, dpkg-divert in preinst scripts is just wrong.

> So in principle, it does not need to be racy. [1]

Having the divert in the preinst is *always* racy - the only reason it
doesn't show in typical Debian is because the packages doing the
diverting are not part of the base install.

> For binutils-multiarch, I suspect C/R/P would be a better way to go.
> Maybe some packages have versioned dependencies on binutils.  I
> suspect the goal was to keep the binutils-multiarch package small,
> without changing binutils very much; see <http://bugs.debian.org/19471>.

Yet even today, lintian does not depend on binutils-multiarch (it's
only a Suggests) and debhelper does not need binutils-multiarch to
cross-build either - Wookey and I proved that a minor patch to dh_split
is all that is needed for debhelper to work with binutils-$triplet
(which is a dependency of the toolchain.) Have to check lintian but I
see no reason why lintian could not work just as well with Depends:
binutils | binutils-multiarch.

The only fly in the ointment is 'as' which would need to be in a
separate package as it cannot be easily multiarched. (Anything that
needs to use 'as' in a cross build will have to know to call $triplet-as
anyway - the toolchain generally.) That doesn't affect lintian or
debhelper, it only affects the small number of packages that have
assembly code in the source which then needs to be cross-built.

> In general, sometimes one wants to steal a filename from another
> package without destroying the file itself (and without causing the
> other package to be removed).  For example, dash and bash fight over
> /bin/sh this way, and I am not sure what else they could do.

Let me clarify things a bit - the problem ONLY occurs if dpkg-divert is
in the PREINST. Postinst scripts appear to be unaffected (because the
diverting package is explicitly more careful about what it does) and
multistrap allows the postinst scripts to run entirely normally.
(postinst scripts have to deal with the situation as-they-find-it and
can make no assumptions about what other packages are installed.)

BTW did anyone realise:

$ file /var/lib/dpkg/info/bash.preinst
/var/lib/dpkg/info/bash.preinst: ELF 64-bit LSB executable, x86-64,
version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux
2.6.18, stripped

WTF?

> > New binutils equiv package just for /usr/bin/as
> 
> What does this mean?

equivs is a way of creating a one-off package that doesn't exist in the
archive but which gets around bugs in the packages that do exist. We
use this method to create the grip-config package.

> [1] If we wanted to allow concurrent installation of packages, there
> would be some scenarios to keep in mind.
> 
>    binutils                    binutils-multiarch
>    --------                    ------------------
>                                check for /usr/bin/objcopy

No need. /usr/bin/objcopy.single is never called so it might as well
not exist, i.e. a Conflicts:

>    unpack /usr/bin/objcopy     add objcopy to /var/lib/dpkg/diversions
>                                don’t rename /usr/bin/objcopy,
>                                  because it wasn’t there at check time
>                                unpack /usr/bin/objcopy --- oops.
> 
> This race can be avoided by checking for /usr/bin/objcopy and renaming it
> in one atomic rename() step.

Or by always forcing binutils-multiarch to unpack AFTER binutils -
obliterating the original files that would have been diverted and never
used. Extra win: packages take up less space on the filesystem.

(Don't forget, every maintainer script takes up space that a
Conflicts:Replaces:Provides: triplet would free - not just the
preinst but the package metadata.)

>    binutils                         binutils-multiarch
>    --------                         ------------------
>    check /var/lib/dpkg/diversions   add objcopy to /var/lib/dpkg/diversions

/var/lib/dpkg/diversions won't exist unless hardcoded by multistrap.

> [2] A thread you might remember. :)
> http://thread.gmane.org/gmane.linux.debian.devel.dpkg.general/9831

(the gmane interface is rubbish on a small screen, this is the direct
link) http://lists.debian.org/debian-devel/2008/06/msg00594.html

Steve Langasek wrote:
> 
> Declarative diversions are a much-needed enhancement to dpkg; there are
> cases one cannot deal with on upgrade without rm'ing one's own package files
> in the prerm in order to handle diversion changes, and that's just nasty. 
> I'm happy to see people thinking about this.



-- 


Neil Williams
=============
http://www.data-freedom.org/
http://www.nosoftwarepatents.com/
http://www.linux.codehelp.co.uk/

Attachment: pgpIsR9Qahh5e.pgp
Description: PGP signature


Reply to: