On Sun, Nov 06, 2016 at 03:59:12PM +0000, James Cowgill wrote:
> On Thu, 3 Nov 2016 13:15:47 +0300 Michael Tokarev <m...@tls.msk.ru> wrote:
> > 03.11.2016 12:46, Toby Speight wrote:
> > > I was able to work around this issue by hand-editing the postinst it to 
> > > add
> > > '|mips*' to the end of $omit (luckily, I don't need MIPS emulation on my
> > > systems).
> > > 
> > > The one thing that stands out about the MIPS registration is that the 
> > > magic
> > > and mask are much longer than for other systems - is it possible that the
> > > kernel can't handle such long patterns?  If so, can this be detected and
> > > avoided?
> > 
> > This change was introduced very recently, see #829243.  But it works fine
> > on my system.  I wonder if 3.16 kernel is unable to process that binfmt
> > while 4.1+ can handle it...  Oh well.
> 
> Looks like this kernel commit added support for longer formats:
> bbaecc088245e840e59a5abe23d69cf7748b3c88
> 
> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/fs/binfmt_misc.c?id=bbaecc088245e840e59a5abe23d69cf7748b3c88
> 
> This is probably what causes this. The above commit exists only in 3.18+

The attached patch only registers the new longer patterns on 3.18+. I still
need another round for the patch. The kernel version check requires bash, and
the naive >> to > change doesn't actually make the script a bash script. But
before I invest more time into this I'd like to know if others agree this change
is the right way.

The other option is to revert the change from #829243 until a better way to
handle the change is done.

Riku

>From 919a7df74f4191092b95b5975e4687b4be0c3bdc Mon Sep 17 00:00:00 2001
From: Riku Voipio <riku.voi...@linaro.org>
Date: Mon, 7 Nov 2016 14:11:23 +0200
Subject: [PATCH] binfmt registering: work around mips registering on kernels

One needs kernel newer than 3.18 to register long form magic with
binfmt_misc. Detect the kernel version, and only register new
mips subarchitectures if kernel is 3.18 or newer. For older
kernel register the shorter version for mips/mipsel.

This solution is sub-optimal:
- if one upgrades kernel, one needs to run dpkg-reconfigure to
  gain the mips architectures
- if one *downgrades* kernel, binfmt registering will fail on boot.

Long term binfmt-support should handle this runtime. 

Closes: 843032
---
 debian/binfmt-update-in | 21 +++++++++++++++++++++
 debian/rules            |  4 ++--
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/debian/binfmt-update-in b/debian/binfmt-update-in
index c0d45a2..9109ac0 100644
--- a/debian/binfmt-update-in
+++ b/debian/binfmt-update-in
@@ -1,3 +1,5 @@
+#!/bin/bash
+set -e
 # check if we're running inside an (lxc) container
 # (we may copy or move this to the postinst script too, to skip installing it)
 grep -zqs ^container= /proc/1/environ && exit 0
@@ -76,6 +78,25 @@ case "$DPKG_MAINTSCRIPT_ARCH" in
   *) omit="$DPKG_MAINTSCRIPT_ARCH" ;;
 esac
 
+# from libc preinst
+linux_compare_versions () {
+    verA=$(($(echo "$1" | sed 's/^\([0-9]*\.[0-9]*\)\([^.0-9]\|$\)/\1.0\2/; s/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1 \* 10000 + \2 \* 100 + \3/')))
+    verB=$(($(echo "$3" | sed 's/^\([0-9]*\.[0-9]*\)\([^.0-9]\|$\)/\1.0\2/; s/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1 \* 10000 + \2 \* 100 + \3/')))
+
+    test $verA -$2 $verB
+}
+
+kernel_ver=`uname -r`
+if linux_compare_versions "$kernel_ver" lt 3.18
+then
+    mips_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08'
+    mips_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+    mipsel_magic='\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00'
+    mipsel_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xfe\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
+    omit="$omit|mipsn32|mipsn32el"
+    echo "Skipping mipsn32 binfmt registering due to too old kernel"
+fi
+
 remove_binfmt() {
     if [ -f /var/lib/binfmts/qemu-$1 ]; then
 	update-binfmts --package @PACKAGE@ --remove qemu-$1 /usr/bin/qemu-$1@SUFFIX@
diff --git a/debian/rules b/debian/rules
index 27df782..8608d52 100755
--- a/debian/rules
+++ b/debian/rules
@@ -254,9 +254,9 @@ ifeq ($(enable_linux_user),enable)
 	# binfmt support
 	for x in postinst prerm; do \
 	    sed -e s/@SUFFIX@/-static/ -e s/@PACKAGE@/qemu-user-static/ \
-		debian/binfmt-update-in >> debian/qemu-user-static.$$x.debhelper ; \
+		debian/binfmt-update-in > debian/qemu-user-static.$$x.debhelper ; \
 	    sed -e s/@SUFFIX@// -e s/@PACKAGE@/qemu-user-binfmt/ \
-		debian/binfmt-update-in >> debian/qemu-user-binfmt.$$x.debhelper ; \
+		debian/binfmt-update-in > debian/qemu-user-binfmt.$$x.debhelper ; \
 	done
 
 endif	# enable_linux_user
-- 
2.1.4

Reply via email to