- Package:
- binfmt-support
- Source:
- binfmt-support
- Description:
- Support for extra binary formats
- Submitter:
- Helmut Grohne
- Date:
- 2019-11-19 11:27:08 UTC
- Severity:
- wishlist
Hi Colin, /usr/share/doc/binfmt-support/README.Debian advises developers to put "update-binfmts --import $PACKAGENAME" into their postinst script and "update-binfmts --unimport $PACKAGENAME" into their prerm script. Doing so has four drawbacks: 1. It is repetitive across each user of binfmt-support. If the call needs to change somehow, we'll have a long transition of a MBF. And yes, it did change (qemu still uses the old interface). 2. If binfmt-support integration is optional (as is the case with qemu), one also must check for the presence of update-binfmts, which makes maintainer scripts longer. 3. If binfmt-support integration is optional (as is the case with qemu) and binfmt-support is installed after the integrating package, the kernel support goes missing. This has been reported as #866756 for instance. As such, optional integration does not work reliably at all, but it is the common way of working with binfmt-support (for instance python suffers from the same issue). 4. We want to get rid of maintainer scripts as much as possible. All of the above issues are addressed by having binfmt-support handle the importing and exporting using dpkg triggers. binfmt-support could declare an interest-noawait on /usr/share/binfmts and import all missing formats automatically. Thus installing binfmt-support would immediately register already installed formats without running configure scripts of other packages again. What do you think? This does pose a significant change in interface and needs to interact with the existing --import/--unimport calls in some way, but after moving there, we'll get rid of a pile of maintainer scripts. Does it have any other drawbacks? I know you know about triggers, so very likely this has crossed your mind already and possibly the --import/--unimport was preparing for triggers. Helmut
This is only because qemu uses the old interface. If it used the "new" (from 2002 ...) interface with files in /usr/share/binfmts/, then the call to "update-binfmts --import" in binfmt-support.postinst would take care of it. I can confirm that this was my ultimate intention, although it's true we haven't quite got there yet. Things that need to be fixed and/or carefully checked: * --import and --unimport exist, but there isn't quite a "sync" operation that imports any binary formats that have been added to /usr/share/binfmts/ and unimports any that have been removed. --unimport immediately followed by --import sort of does the job, but is invasive. * qemu-user-static does conditional registration partly in order to avoid registering a binary format for the native architecture, which would immediately crash the system. This could surely be done in debian/rules instead, conditionally installing binary format files for use by --import, but the consequences are serious if it goes wrong so we need to be careful. * We'll probably have to audit all other relevant maintainer scripts for weird stuff too. * I don't think the duplication with existing --import/--unimport calls would be a serious problem. As long as --unimport goes with actually removing the file, they should IIRC be idempotent, though of course we need to check that.
Hi Colin,
I disagree here. If qemu-user-static's postinst runs before
binfmt-support is unpacked, it'll skip the update-binfmts calls
regardless of whether it uses --import or the old interface. This is
only dependent on the order of binfmts-support unpack vs.
qemu-user-static.postinst.
Of course for getting the trigger behaviour that I was asking for, we
must change qemu. To that end, I've sent a patch to #866756 that
converts it to use --import/--unimport. I agree this is part of the
solution, but this part is insufficient. (I had to wait for greylisting,
to know the bug number of this bug.)
Great!
How about this pseudo code being added to binfmt-support.postinst into a
section that acts on triggers?
for fmt in /var/lib/binfmts/*; do
fmt=${fmt#/var/lib/binfmts/}
if ! test -e "/usr/share/binfmts/$fmt" || \
test "/usr/share/binfmts/$fmt" -nt "/var/lib/binfmts/$fmt"; then
update-binfmts --unimport "$fmt"
fi
done
for fmt in /usr/share/binfmts/*; do
fmt=${fmt#/usr/share/binfmts/}
if ! test -e "/var/lib/binfmts/$fmt"; then
update-binfmts --import "$fmt"
fi
done
Unless I am mistaken, this is the sync operation you are looking for.
As bad as it looks, this is actually easy. The condition is on the host
architecture, which is something we know at build time. We can do the
heavy lifting at build time and check the generated /usr/share/binfmts/*
before installing the package. The format files for native (and sibling)
architectures simply go missing. My patch for #866756 does that.
Regardless of the patch, bad things do happen if you attempt to install
say qemu-user-static:arm64 on and amd64 system. I don't see any use case
for this though given that qemu-user-static is M-A:foreign.
Yes. To the best of my knowledge, this has not been done by anyone yet.
Great.
So provided someone checked maintainer scripts for weird stuff, would
you add my sync code to binfmt-support with a interest-noawait on
/usr/share/binfmts?
Helmut
It'll skip it in qemu-user-static.postinst, yes, but then when binfmt-support is configured it will catch up with any format files that are already installed. Are you missing something or am I? Thanks. I haven't gone through it in detail but it looks credible enough (except that "command -v" is I think non-portable, which is why binfmt-support's README.Debian recommends the use of "which"). How about the versioned Conflicts suggested in binfmt-support's README.Debian to ensure that --unimport is available? (Or versioned Breaks would probably do as well.) I think this may work, but I'd like to at least investigate doing it in update-binfmts's C code instead. The older I get the less interested I am in following careful logic in shell. :-) Agreed - I just wanted to flag it as needing care. As I say I'd prefer something like "update-binfmts --sync", but in principle yes. (Hopefully I will have time to have a look at that soonish.)
Hi Colin, I am. Thank you for insisting. I was missing the bare update-binfmts --import call. So the patch I sent fully resolves the problem on the qemu side without further changes to binfmt-support. \o/ Triggers are still nice to have. Oh, I missed those. I vaguely question their utility though given that you'd have to upgrade from stretch to bullseye directly to experience an issue. Oh sure. I do prefer less code in maintainer scripts. :) Given that I missed the --import part, I'm less interested in the "soon" part now. ;) Thank you for the quick and helpful replies. Helmut