(For the benefit of Holger and the list, this is the log from a discussion I had today with Wookey about issues arising from multistrap creating cross-building chroots and foreign architecture root filesystems where debootstrap simply cannot cope.) Problem: ======== dpkg-divert enforces a double stage installation of the base system first so that the files exist to be diverted beforehand. This is implemented in the maintainer scripts which means foreign chroots cannot support dpkg-divert. In native environments, dpkg --unpack is called which intersperses the unpacking of the diverted package with execution of the maintainer script to move the diverted files aside, then unpacks the diverting package. A foreign environment means that dpkg --unpack is impossible, therefore in multistrap, dpkg -X is used. Unpacking first and then configure natively (after first boot for foreign). Extracting a package being diverted and the diverting package at the same time causes a race condition. Currently packages are sorted alphabetically but could be in directory order or modification time order or random. Conceptually, a diverting package actually pre-depends on the package being diverted. In practice, dpkg-divert does not fail (so this issue does not generate bug reports) and diverting packages depend on the packages being diverted and therefore can expect the current Debian dual-stage install to ensure that the package being diverted already exists on the filesystem. (i.e. debootstrap puts the Priority: required packages in first and then adds packages that may use diverts.) Without a declarative list, multistrap cannot determine which packages use diverts (the maintainer scripts may call dpkg-divert explicitly or may use variables and sub routines, can use shell or perl to call dpkg-divert - it becomes impossible to parse). (I'm hoping that piuparts may have the logs to indicate exactly which packages use dpkg-divert and how, across the entire archive.) For foreign chroot support, we need to remove the interleaving requirement whereby binutils must be unpacked, then the binutils-multiarch preinst executed (to move the diverted files aside), then binutils-multiarch unpacked. # dpkg -X binutils / # dpkg-deb -e binutils-multiarch_foo_arch.deb /tmp # /tmp/path/binutils-multiarch.preinst install (files in binutils package are diverted using perl) # dpkg -X binutils-multiarch In reality, NONE of the diverted files are actually used because dpkg-divert renames them and in order for any package to use the $file.single or $file.diverted, that package must already depend on the diverting package. i.e. packages don't call /usr/bin/objcopy.single - packages work with /usr/bin/objcopy whether that is the binutils version or the binutils-multiarch version. Therefore, when a divert is used, the actual diversion is pointless as the thing being diverted might just as well be removed/replaced. Hence a Conflicts: Replaces: Provides: mechanism would seem more appropriate - why is this not done? Fixes for now: ============== Need a declarative list of dpkg-diverts including the name of the binary package DIVERTED and the package calling dpkg-divert. Enhance multistrap error handling to declare a conflict if both the diverting and the diverted packages are requested. New binutils equiv package just for /usr/bin/as multistrap too ignore the package being diverted and only install the diverting package. fix dh_strip - alternative to installing binutils-multiarch after squeeze: (NY)! ============== Seek removal of dpkg-diverts and replacements with Pre-Depends| alternative depends|virtual package corner cases and other unexpected situations where this won't work. Attached is a real log from the experimental multiarch setup which shows the issue - a normal package build fails because objcopy does not exist, despite binutils and binutils-multiarch appearing to be properly installed. The diversion has happened but because the diversion took place AFTER both packages were unpacked, diverting the files actually means that the original file has disappeared completely and which file you get is essentially random. # objcopy bash: objcopy: command not found Reinstalling both binutils and binutils-multiarch fixes the problem - as long as either both are specified in the same command or binutils is re-installed first. What have I missed? (quite a lot probably!) -- Neil Williams ============= http://www.data-freedom.org/ http://www.linux.codehelp.co.uk/ http://e-mail.is-not-s.ms/
Attachment:
dpkg-divert.log.gz
Description: Binary data
Attachment:
pgpBohGRiVdyM.pgp
Description: PGP signature