Hi Colin, On Mon, Nov 18, 2019 at 03:22:53PM +0100, Colin Watson wrote: > > 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). > > 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 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.) > 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: Great! > * --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. 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. > * 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. 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. > * We'll probably have to audit all other relevant maintainer scripts > for weird stuff too. Yes. To the best of my knowledge, this has not been done by anyone yet. > * 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. 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