diff mbox

linux-user: Original qemu-binfmt-conf.h is only able to write configuration into /proc/sys/fs/binfmt_misc, and the configuration is lost on reboot.

Message ID 1454011696-2119-1-git-send-email-laurent@vivier.eu (mailing list archive)
State New, archived
Headers show

Commit Message

Laurent Vivier Jan. 28, 2016, 8:08 p.m. UTC
This script can configure debian and systemd services to restore
configuration on reboot. Moreover, it is able to manage binfmt
credential and to configure the path of the interpreter.

List of supported CPU is:

i386 i486 alpha arm sparc32plus ppc ppc64 ppc64le
m68k mips mipsel mipsn32 mipsn32el mips64 mips64el
sh4 sh4eb s390x aarch64

Usage: qemu-binfmt-conf.sh [--qemu-path PATH][--debian [--exportdir PATH]]
                           [--help][--credential yes|no][--systemd CPU]

       Configure binfmt_misc to use qemu interpreter

       --help:       display this usage
       --qemu-path:  set path to qemu interpreter (/usr/local/bin)
       --debian:     don't write into /proc,
                     instead generate update-binfmts templates
       --systemd:    don't write into /proc,
                     instead generate file for systemd-binfmt.service
                     for the given CPU
       --exportdir:  define where to write update-binfmts templates
                     (/usr/share/binfmts)
       --credential: if yes, credential an security tokens are
                     calculated according to the binary to interpret

    To import templates with update-binfmts, use :

        sudo update-binfmts --importdir /usr/share/binfmts --import qemu-CPU

    To remove interpreter, use :

        sudo update-binfmts --package qemu-CPU --remove qemu-CPU /usr/local/bin

    With systemd, binfmt files are loaded by systemd-binfmt.service

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 scripts/qemu-binfmt-conf.sh | 371 ++++++++++++++++++++++++++++++++++++--------
 1 file changed, 302 insertions(+), 69 deletions(-)
 mode change 100644 => 100755 scripts/qemu-binfmt-conf.sh

Comments

Alexander Graf Jan. 28, 2016, 8:20 p.m. UTC | #1
On 01/28/2016 09:08 PM, Laurent Vivier wrote:
> This script can configure debian and systemd services to restore
> configuration on reboot. Moreover, it is able to manage binfmt
> credential and to configure the path of the interpreter.
>
> List of supported CPU is:
>
> i386 i486 alpha arm sparc32plus ppc ppc64 ppc64le
> m68k mips mipsel mipsn32 mipsn32el mips64 mips64el
> sh4 sh4eb s390x aarch64
>
> Usage: qemu-binfmt-conf.sh [--qemu-path PATH][--debian [--exportdir PATH]]
>                             [--help][--credential yes|no][--systemd CPU]
>
>         Configure binfmt_misc to use qemu interpreter
>
>         --help:       display this usage
>         --qemu-path:  set path to qemu interpreter (/usr/local/bin)
>         --debian:     don't write into /proc,
>                       instead generate update-binfmts templates
>         --systemd:    don't write into /proc,
>                       instead generate file for systemd-binfmt.service
>                       for the given CPU
>         --exportdir:  define where to write update-binfmts templates
>                       (/usr/share/binfmts)
>         --credential: if yes, credential an security tokens are
>                       calculated according to the binary to interpret
>
>      To import templates with update-binfmts, use :
>
>          sudo update-binfmts --importdir /usr/share/binfmts --import qemu-CPU
>
>      To remove interpreter, use :
>
>          sudo update-binfmts --package qemu-CPU --remove qemu-CPU /usr/local/bin
>
>      With systemd, binfmt files are loaded by systemd-binfmt.service
>
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---
>   scripts/qemu-binfmt-conf.sh | 371 ++++++++++++++++++++++++++++++++++++--------
>   1 file changed, 302 insertions(+), 69 deletions(-)
>   mode change 100644 => 100755 scripts/qemu-binfmt-conf.sh
>
> diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
> old mode 100644
> new mode 100755
> index 289b1a3..f34b282
> --- a/scripts/qemu-binfmt-conf.sh
> +++ b/scripts/qemu-binfmt-conf.sh
> @@ -1,72 +1,305 @@
>   #!/bin/sh
>   # enable automatic i386/ARM/M68K/MIPS/SPARC/PPC/s390 program execution by the kernel
>   
> -# load the binfmt_misc module
> -if [ ! -d /proc/sys/fs/binfmt_misc ]; then
> -  /sbin/modprobe binfmt_misc
> -fi
> -if [ ! -f /proc/sys/fs/binfmt_misc/register ]; then
> -  mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
> -fi
> -
> -# probe cpu type
> -cpu=`uname -m`
> -case "$cpu" in
> -  i386|i486|i586|i686|i86pc|BePC|x86_64)
> -    cpu="i386"
> -  ;;
> -  m68k)
> -    cpu="m68k"
> -  ;;
> -  mips*)
> -    cpu="mips"
> -  ;;
> -  "Power Macintosh"|ppc|ppc64)
> -    cpu="ppc"
> -  ;;
> -  armv[4-9]*)
> -    cpu="arm"
> -  ;;
> -esac
> -
> -# register the interpreter for each cpu except for the native one
> -if [ $cpu != "i386" ] ; then
> -    echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
> -    echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
> -fi
> -if [ $cpu != "alpha" ] ; then
> -    echo ':alpha:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-alpha:' > /proc/sys/fs/binfmt_misc/register
> -fi
> -if [ $cpu != "arm" ] ; then
> -    echo   ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-arm:' > /proc/sys/fs/binfmt_misc/register
> -    echo   ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-armeb:' > /proc/sys/fs/binfmt_misc/register
> -fi
> -if [ $cpu != "aarch64" ] ; then
> -    echo ':aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-aarch64:' > /proc/sys/fs/binfmt_misc/register
> -fi
> -if [ $cpu != "sparc" ] ; then
> -    echo   ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sparc:' > /proc/sys/fs/binfmt_misc/register
> -fi
> -if [ $cpu != "ppc" ] ; then
> -    echo   ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-ppc:' > /proc/sys/fs/binfmt_misc/register
> -fi
> -if [ $cpu != "m68k" ] ; then
> -    echo   'Please check cpu value and header information for m68k!'
> -    echo   ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-m68k:' > /proc/sys/fs/binfmt_misc/register
> -fi
> -if [ $cpu != "mips" ] ; then
> -    # FIXME: We could use the other endianness on a MIPS host.
> -    echo   ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips:' > /proc/sys/fs/binfmt_misc/register
> -    echo   ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsel:' > /proc/sys/fs/binfmt_misc/register
> -    echo   ':mipsn32:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mipsn32:' > /proc/sys/fs/binfmt_misc/register
> -    echo   ':mipsn32el:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsn32el:' > /proc/sys/fs/binfmt_misc/register
> -    echo   ':mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips64:' > /proc/sys/fs/binfmt_misc/register
> -    echo   ':mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mips64el:' > /proc/sys/fs/binfmt_misc/register
> -fi
> -if [ $cpu != "sh" ] ; then
> -    echo    ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-sh4:' > /proc/sys/fs/binfmt_misc/register
> -    echo    ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sh4eb:' > /proc/sys/fs/binfmt_misc/register
> -fi
> -if [ $cpu != "s390x" ] ; then
> -    echo   ':s390x:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-s390x:' > /proc/sys/fs/binfmt_misc/register
> -fi
> +qemu_target_list="i386 i486 alpha arm sparc32plus ppc ppc64 ppc64le m68k \
> +                  mips mipsel mipsn32 mipsn32el mips64 mips64el \
> +                  sh4 sh4eb s390x aarch64"
> +
> +i386_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00'
> +i386_mask='\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
> +i386_family=i386
> +
> +i486_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00'
> +i486_mask='\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
> +i486_family=i386
> +
> +alpha_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90'
> +alpha_mask='\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
> +alpha_family=alpha
> +
> +arm_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00'
> +arm_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
> +arm_family=arm
> +
> +armeb_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28'
> +armeb_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
> +armeb_family=arm
> +
> +sparc_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02'
> +sparc_mask='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
> +sparc_family=sparc
> +
> +sparc32plus_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x12'
> +sparc32plus_mask='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
> +sparc32plus_family=sparc
> +
> +ppc_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14'
> +ppc_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
> +ppc_family=ppc
> +
> +ppc64_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15'
> +ppc64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
> +ppc64_family=ppc
> +
> +ppc64le_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15\x00'
> +ppc64le_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\x00'
> +ppc64le_family=ppc
> +
> +m68k_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04'
> +m68k_mask='\xff\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
> +m68k_family=m68k
> +
> +# FIXME: We could use the other endianness on a MIPS host.
> +
> +mips_magic='\x7fELF\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
> +mips_family=mips
> +
> +mipsel_magic='\x7fELF\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\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
> +mipsel_family=mips
> +
> +mipsn32_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08'
> +mipsn32_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
> +mipsn32_family=mips
> +
> +mipsn32el_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00'
> +mipsn32el_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
> +mipsn32el_family=mips
> +
> +mips64_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08'
> +mips64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
> +mips64_family=mips
> +
> +mips64el_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00'
> +mips64el_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
> +mips64el_family=mips
> +
> +sh4_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00'
> +sh4_mask='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
> +sh4_family=sh4
> +
> +sh4eb_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a'
> +sh4eb_mask='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
> +sh4eb_family=sh4
> +
> +s390x_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16'
> +s390x_mask='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
> +s390x_family=s390x
> +
> +aarch64_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00'
> +aarch64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
> +aarch64_family=aarch64
> +
> +qemu_get_family() {
> +    cpu=$(uname -m)
> +    case "$cpu" in
> +    i386|i486|i586|i686|i86pc|BePC|x86_64)
> +        echo "i386"
> +        ;;
> +    mips*)
> +        echo "mips"
> +        ;;
> +    "Power Macintosh")
> +        echo "ppc"
> +        ;;
> +    armv[4-9]*)
> +        echo "arm"
> +        ;;
> +    sparc*)
> +        echo "sparc"
> +        ;;
> +    *)
> +        echo "$cpu"
> +        ;;
> +    esac
> +}
> +
> +usage() {
> +    cat <<!EOF
> +Usage: qemu-binfmt-conf.sh [--qemu-path PATH][--debian [--exportdir PATH]]
> +                           [--help][--credential yes|no][--systemd CPU]
> +
> +       Configure binfmt_misc to use qemu interpreter
> +
> +       --help:       display this usage
> +       --qemu-path:  set path to qemu interpreter ($QEMU_PATH)
> +       --debian:     don't write into /proc,
> +                     instead generate update-binfmts templates
> +       --systemd:    don't write into /proc,
> +                     instead generate file for systemd-binfmt.service
> +                     for the given CPU
> +       --exportdir:  define where to write update-binfmts templates
> +                     ($EXPORTDIR)
> +       --credential: if yes, credential an security tokens are
> +                     calculated according to the binary to interpret
> +
> +    To import templates with update-binfmts, use :
> +
> +        sudo update-binfmts --importdir $EXPORTDIR --import qemu-CPU
> +
> +    To remove interpreter, use :
> +
> +        sudo update-binfmts --package qemu-CPU --remove qemu-CPU $QEMU_PATH
> +
> +    With systemd, binfmt files are loaded by systemd-binfmt.service
> +
> +    where CPU is one of:
> +
> +!EOF
> +    echo -n "    "
> +    for CPU in $qemu_target_list ;
> +    do
> +        echo -n "$CPU "
> +    done
> +    echo
> +}
> +
> +qemu_check_bintfmt_misc() {
> +    # load the binfmt_misc module
> +    if [ ! -d /proc/sys/fs/binfmt_misc ]; then
> +      if ! /sbin/modprobe binfmt_misc ; then
> +          exit 1
> +      fi
> +    fi
> +    if [ ! -f /proc/sys/fs/binfmt_misc/register ]; then
> +      if ! mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc ; then
> +          exit 1
> +      fi
> +    fi
> +
> +    if [ ! -w /proc/sys/fs/binfmt_misc/register ] ; then
> +        echo "ERROR: cannot write to /proc/sys/fs/binfmt_misc/register" 1>&2
> +        exit 1
> +    fi
> +}
> +
> +installed_dpkg() {
> +    dpkg --status "$1" > /dev/null 2>&1
> +}
> +
> +qemu_check_debian() {
> +    if [ ! -e /etc/debian_version ] ; then
> +        echo "ERROR: this script works only on Debian based distro" 1>&2
> +        exit 1
> +    fi
> +    if ! installed_dpkg binfmt-support ; then
> +        echo "ERROR: package binfmt-support is needed !" 1>&2
> +        exit 1
> +    fi
> +}
> +
> +qemu_check_systemd() {
> +    if ! systemctl -q is-enabled systemd-binfmt.service ; then
> +        echo "ERROR: systemd-binfmt.service is missing or disabled !" 1>&2
> +        exit 1
> +    fi

One envisioned use case of this script would be file generation inside 
of a package build. During the package build, there may not be systemd 
running at all - or it might just be a chroot.

So this check needs to be optional :).

> +    if [ "$UID" != "0" ] ; then
> +        echo "ERROR: you must be root to be able to write systemd configuration files !" 1>&2
> +        exit 1
> +    fi

Better check the directory permissions and see whether you have write 
access to /etc/binfmt.d?

> +}
> +
> +qemu_register_interpreter() {
> +    echo "Setting $qemu as binfmt interpreter for $cpu"
> +    echo ":qemu-$cpu:M::$magic:$mask:$qemu:$FLAGS" > /proc/sys/fs/binfmt_misc/register
> +}
> +
> +qemu_generate_systemd() {
> +    echo "Setting $qemu as binfmt interpreter for $cpu for systemd-binfmt.service"
> +    echo ":qemu-$cpu:M::$magic:$mask:$qemu:$FLAGS" > "/etc/binfmt.d/qemu-$cpu.conf"

This is duplicating the binfmt lines. While not terrible, I think it'd 
be awesome if we could move it out into a separate function that gets 
called from the self-register and systemd-register functions.

> +}
> +
> +qemu_generate_packages() {

This is the debian version, right? Should be reflected in its function name.

> +    cat > "$EXPORTDIR/qemu-$cpu" <<!EOF
> +package qemu-$cpu
> +interpreter $qemu
> +magic $magic
> +mask $mask
> +!EOF
> +    if [ "$FLAGS" = "OC" ] ; then
> +        echo "credentials yes" >> "$EXPORTDIR/qemu-$cpu"
> +    fi
> +}
> +
> +qemu_set_binfmts() {
> +    # probe cpu type
> +    host_family=$(qemu_get_family)
> +
> +    # register the interpreter for each cpu except for the native one
> +
> +    for cpu in ${qemu_target_list} ; do
> +        magic=$(eval echo \$${cpu}_magic)
> +        mask=$(eval echo \$${cpu}_mask)
> +        family=$(eval echo \$${cpu}_family)

Debian had quite sophisticated groupings and logic to not register 
certain handlers under certain circumstances. Michael, can you please 
double-check that we're not regressing for you guys?

> +
> +        if [ "$magic" = "" -o "$mask" = "" -o "$family" = "" ] ; then
> +            echo "INTERNAL ERROR: unknown cpu $cpu" 1>&2
> +            continue
> +        fi
> +
> +        qemu="$QEMU_PATH/qemu-$cpu"
> +        if [ "$cpu" = "i486" ] ; then
> +            qemu="$QEMU_PATH/qemu-i386"
> +        fi
> +
> +        if [ "$host_family" != "$family" ] ; then
> +            $BINFMT_SET
> +        fi
> +    done
> +}
> +
> +BINFMT_SET=qemu_register_interpreter
> +QEMU_PATH=/usr/local/bin
> +EXPORTDIR="/usr/share/binfmts"
> +CHECK=qemu_check_bintfmt_misc
> +FLAGS=""
> +
> +options=$(getopt -o ds:Q:e:hc: -l debian,systemd:,qemu-path:,exportdir:,help,credential: -- "$@")
> +eval set -- "$options"
> +
> +while true ; do
> +    case "$1" in
> +    -d|--debian)
> +        CHECK=qemu_check_debian
> +        BINFMT_SET=qemu_generate_packages
> +        ;;
> +    -s|--systemd)
> +        CHECK=qemu_check_systemd
> +        BINFMT_SET=qemu_generate_systemd
> +        shift
> +        qemu_target_list="$1"
> +        ;;
> +    -Q|--qemu-path)
> +        shift
> +        QEMU_PATH="$1"
> +        ;;
> +    -e|--exportdir)
> +        shift
> +        EXPORTDIR="$1"
> +        if [ ! -d "$EXPORTDIR" ] ; then
> +            echo "ERROR: $EXPORTDIR doesn't exist" 1>&2
> +            exit 1
> +        fi
> +        ;;
> +    -h|--help)
> +        usage
> +        exit 1
> +        ;;
> +    -c|--credential)
> +        shift
> +        if [ "$1" = "yes" ] ; then
> +            FLAGS="OC"
> +        else
> +            FLAGS=""
> +        fi
> +        ;;
> +    *)
> +        break
> +        ;;
> +    esac
> +    shift
> +done
> +
> +$CHECK
> +qemu_set_binfmts

Ah, nice, so the old behavior does get preserved. Great :)

Alex
Laurent Vivier Jan. 28, 2016, 8:33 p.m. UTC | #2
Le 28/01/2016 21:20, Alexander Graf a écrit :
> 
> 
> On 01/28/2016 09:08 PM, Laurent Vivier wrote:
>> This script can configure debian and systemd services to restore
>> configuration on reboot. Moreover, it is able to manage binfmt
>> credential and to configure the path of the interpreter.
>>
>> List of supported CPU is:
>>
>> i386 i486 alpha arm sparc32plus ppc ppc64 ppc64le
>> m68k mips mipsel mipsn32 mipsn32el mips64 mips64el
>> sh4 sh4eb s390x aarch64
>>
>> Usage: qemu-binfmt-conf.sh [--qemu-path PATH][--debian [--exportdir
>> PATH]]
>>                             [--help][--credential yes|no][--systemd CPU]
>>
>>         Configure binfmt_misc to use qemu interpreter
>>
>>         --help:       display this usage
>>         --qemu-path:  set path to qemu interpreter (/usr/local/bin)
>>         --debian:     don't write into /proc,
>>                       instead generate update-binfmts templates
>>         --systemd:    don't write into /proc,
>>                       instead generate file for systemd-binfmt.service
>>                       for the given CPU
>>         --exportdir:  define where to write update-binfmts templates
>>                       (/usr/share/binfmts)
>>         --credential: if yes, credential an security tokens are
>>                       calculated according to the binary to interpret
>>
>>      To import templates with update-binfmts, use :
>>
>>          sudo update-binfmts --importdir /usr/share/binfmts --import
>> qemu-CPU
>>
>>      To remove interpreter, use :
>>
>>          sudo update-binfmts --package qemu-CPU --remove qemu-CPU
>> /usr/local/bin
>>
>>      With systemd, binfmt files are loaded by systemd-binfmt.service
>>
>> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
>> ---
>>   scripts/qemu-binfmt-conf.sh | 371
>> ++++++++++++++++++++++++++++++++++++--------
>>   1 file changed, 302 insertions(+), 69 deletions(-)
>>   mode change 100644 => 100755 scripts/qemu-binfmt-conf.sh
>>
>> diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
>> old mode 100644
>> new mode 100755
>> index 289b1a3..f34b282
>> --- a/scripts/qemu-binfmt-conf.sh
>> +++ b/scripts/qemu-binfmt-conf.sh
>> @@ -1,72 +1,305 @@
>>   #!/bin/sh
>>   # enable automatic i386/ARM/M68K/MIPS/SPARC/PPC/s390 program
>> execution by the kernel
>>   -# load the binfmt_misc module
>> -if [ ! -d /proc/sys/fs/binfmt_misc ]; then
>> -  /sbin/modprobe binfmt_misc
>> -fi
>> -if [ ! -f /proc/sys/fs/binfmt_misc/register ]; then
>> -  mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
>> -fi
>> -
>> -# probe cpu type
>> -cpu=`uname -m`
>> -case "$cpu" in
>> -  i386|i486|i586|i686|i86pc|BePC|x86_64)
>> -    cpu="i386"
>> -  ;;
>> -  m68k)
>> -    cpu="m68k"
>> -  ;;
>> -  mips*)
>> -    cpu="mips"
>> -  ;;
>> -  "Power Macintosh"|ppc|ppc64)
>> -    cpu="ppc"
>> -  ;;
>> -  armv[4-9]*)
>> -    cpu="arm"
>> -  ;;
>> -esac
>> -
>> -# register the interpreter for each cpu except for the native one
>> -if [ $cpu != "i386" ] ; then
>> -    echo
>> ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:'
>> > /proc/sys/fs/binfmt_misc/register
>> -    echo
>> ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:'
>> > /proc/sys/fs/binfmt_misc/register
>> -fi
>> -if [ $cpu != "alpha" ] ; then
>> -    echo
>> ':alpha:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-alpha:'
>> > /proc/sys/fs/binfmt_misc/register
>> -fi
>> -if [ $cpu != "arm" ] ; then
>> -    echo  
>> ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-arm:'
>> > /proc/sys/fs/binfmt_misc/register
>> -    echo  
>> ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-armeb:'
>> > /proc/sys/fs/binfmt_misc/register
>> -fi
>> -if [ $cpu != "aarch64" ] ; then
>> -    echo
>> ':aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-aarch64:'
>> > /proc/sys/fs/binfmt_misc/register
>> -fi
>> -if [ $cpu != "sparc" ] ; then
>> -    echo  
>> ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sparc:'
>> > /proc/sys/fs/binfmt_misc/register
>> -fi
>> -if [ $cpu != "ppc" ] ; then
>> -    echo  
>> ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-ppc:'
>> > /proc/sys/fs/binfmt_misc/register
>> -fi
>> -if [ $cpu != "m68k" ] ; then
>> -    echo   'Please check cpu value and header information for m68k!'
>> -    echo  
>> ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-m68k:'
>> > /proc/sys/fs/binfmt_misc/register
>> -fi
>> -if [ $cpu != "mips" ] ; then
>> -    # FIXME: We could use the other endianness on a MIPS host.
>> -    echo  
>> ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips:'
>> > /proc/sys/fs/binfmt_misc/register
>> -    echo  
>> ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsel:'
>> > /proc/sys/fs/binfmt_misc/register
>> -    echo  
>> ':mipsn32:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mipsn32:'
>> > /proc/sys/fs/binfmt_misc/register
>> -    echo  
>> ':mipsn32el:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsn32el:'
>> > /proc/sys/fs/binfmt_misc/register
>> -    echo  
>> ':mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips64:'
>> > /proc/sys/fs/binfmt_misc/register
>> -    echo  
>> ':mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mips64el:'
>> > /proc/sys/fs/binfmt_misc/register
>> -fi
>> -if [ $cpu != "sh" ] ; then
>> -    echo   
>> ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-sh4:'
>> > /proc/sys/fs/binfmt_misc/register
>> -    echo   
>> ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sh4eb:'
>> > /proc/sys/fs/binfmt_misc/register
>> -fi
>> -if [ $cpu != "s390x" ] ; then
>> -    echo  
>> ':s390x:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-s390x:'
>> > /proc/sys/fs/binfmt_misc/register
>> -fi
>> +qemu_target_list="i386 i486 alpha arm sparc32plus ppc ppc64 ppc64le
>> m68k \
>> +                  mips mipsel mipsn32 mipsn32el mips64 mips64el \
>> +                  sh4 sh4eb s390x aarch64"
>> +
>> +i386_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00'
>>
>> +i386_mask='\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
>>
>> +i386_family=i386
>> +
>> +i486_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00'
>>
>> +i486_mask='\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
>>
>> +i486_family=i386
>> +
>> +alpha_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90'
>>
>> +alpha_mask='\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
>>
>> +alpha_family=alpha
>> +
>> +arm_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00'
>>
>> +arm_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
>>
>> +arm_family=arm
>> +
>> +armeb_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28'
>>
>> +armeb_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
>>
>> +armeb_family=arm
>> +
>> +sparc_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02'
>>
>> +sparc_mask='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
>>
>> +sparc_family=sparc
>> +
>> +sparc32plus_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x12'
>>
>> +sparc32plus_mask='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
>>
>> +sparc32plus_family=sparc
>> +
>> +ppc_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14'
>>
>> +ppc_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
>>
>> +ppc_family=ppc
>> +
>> +ppc64_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15'
>>
>> +ppc64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
>>
>> +ppc64_family=ppc
>> +
>> +ppc64le_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15\x00'
>>
>> +ppc64le_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\x00'
>>
>> +ppc64le_family=ppc
>> +
>> +m68k_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04'
>>
>> +m68k_mask='\xff\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
>>
>> +m68k_family=m68k
>> +
>> +# FIXME: We could use the other endianness on a MIPS host.
>> +
>> +mips_magic='\x7fELF\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
>>
>> +mips_family=mips
>> +
>> +mipsel_magic='\x7fELF\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\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
>>
>> +mipsel_family=mips
>> +
>> +mipsn32_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08'
>>
>> +mipsn32_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
>>
>> +mipsn32_family=mips
>> +
>> +mipsn32el_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00'
>>
>> +mipsn32el_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
>>
>> +mipsn32el_family=mips
>> +
>> +mips64_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08'
>>
>> +mips64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
>>
>> +mips64_family=mips
>> +
>> +mips64el_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00'
>>
>> +mips64el_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
>>
>> +mips64el_family=mips
>> +
>> +sh4_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00'
>>
>> +sh4_mask='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
>>
>> +sh4_family=sh4
>> +
>> +sh4eb_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a'
>>
>> +sh4eb_mask='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
>>
>> +sh4eb_family=sh4
>> +
>> +s390x_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16'
>>
>> +s390x_mask='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
>>
>> +s390x_family=s390x
>> +
>> +aarch64_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00'
>>
>> +aarch64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
>>
>> +aarch64_family=aarch64
>> +
>> +qemu_get_family() {
>> +    cpu=$(uname -m)
>> +    case "$cpu" in
>> +    i386|i486|i586|i686|i86pc|BePC|x86_64)
>> +        echo "i386"
>> +        ;;
>> +    mips*)
>> +        echo "mips"
>> +        ;;
>> +    "Power Macintosh")
>> +        echo "ppc"
>> +        ;;
>> +    armv[4-9]*)
>> +        echo "arm"
>> +        ;;
>> +    sparc*)
>> +        echo "sparc"
>> +        ;;
>> +    *)
>> +        echo "$cpu"
>> +        ;;
>> +    esac
>> +}
>> +
>> +usage() {
>> +    cat <<!EOF
>> +Usage: qemu-binfmt-conf.sh [--qemu-path PATH][--debian [--exportdir
>> PATH]]
>> +                           [--help][--credential yes|no][--systemd CPU]
>> +
>> +       Configure binfmt_misc to use qemu interpreter
>> +
>> +       --help:       display this usage
>> +       --qemu-path:  set path to qemu interpreter ($QEMU_PATH)
>> +       --debian:     don't write into /proc,
>> +                     instead generate update-binfmts templates
>> +       --systemd:    don't write into /proc,
>> +                     instead generate file for systemd-binfmt.service
>> +                     for the given CPU
>> +       --exportdir:  define where to write update-binfmts templates
>> +                     ($EXPORTDIR)
>> +       --credential: if yes, credential an security tokens are
>> +                     calculated according to the binary to interpret
>> +
>> +    To import templates with update-binfmts, use :
>> +
>> +        sudo update-binfmts --importdir $EXPORTDIR --import qemu-CPU
>> +
>> +    To remove interpreter, use :
>> +
>> +        sudo update-binfmts --package qemu-CPU --remove qemu-CPU
>> $QEMU_PATH
>> +
>> +    With systemd, binfmt files are loaded by systemd-binfmt.service
>> +
>> +    where CPU is one of:
>> +
>> +!EOF
>> +    echo -n "    "
>> +    for CPU in $qemu_target_list ;
>> +    do
>> +        echo -n "$CPU "
>> +    done
>> +    echo
>> +}
>> +
>> +qemu_check_bintfmt_misc() {
>> +    # load the binfmt_misc module
>> +    if [ ! -d /proc/sys/fs/binfmt_misc ]; then
>> +      if ! /sbin/modprobe binfmt_misc ; then
>> +          exit 1
>> +      fi
>> +    fi
>> +    if [ ! -f /proc/sys/fs/binfmt_misc/register ]; then
>> +      if ! mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
>> ; then
>> +          exit 1
>> +      fi
>> +    fi
>> +
>> +    if [ ! -w /proc/sys/fs/binfmt_misc/register ] ; then
>> +        echo "ERROR: cannot write to
>> /proc/sys/fs/binfmt_misc/register" 1>&2
>> +        exit 1
>> +    fi
>> +}
>> +
>> +installed_dpkg() {
>> +    dpkg --status "$1" > /dev/null 2>&1
>> +}
>> +
>> +qemu_check_debian() {
>> +    if [ ! -e /etc/debian_version ] ; then
>> +        echo "ERROR: this script works only on Debian based distro" 1>&2
>> +        exit 1
>> +    fi
>> +    if ! installed_dpkg binfmt-support ; then
>> +        echo "ERROR: package binfmt-support is needed !" 1>&2
>> +        exit 1
>> +    fi
>> +}
>> +
>> +qemu_check_systemd() {
>> +    if ! systemctl -q is-enabled systemd-binfmt.service ; then
>> +        echo "ERROR: systemd-binfmt.service is missing or disabled !"
>> 1>&2
>> +        exit 1
>> +    fi
> 
> One envisioned use case of this script would be file generation inside
> of a package build. During the package build, there may not be systemd
> running at all - or it might just be a chroot.
> 
> So this check needs to be optional :).

OK

>> +    if [ "$UID" != "0" ] ; then
>> +        echo "ERROR: you must be root to be able to write systemd
>> configuration files !" 1>&2
>> +        exit 1
>> +    fi
> 
> Better check the directory permissions and see whether you have write
> access to /etc/binfmt.d?

OK

>> +}
>> +
>> +qemu_register_interpreter() {
>> +    echo "Setting $qemu as binfmt interpreter for $cpu"
>> +    echo ":qemu-$cpu:M::$magic:$mask:$qemu:$FLAGS" >
>> /proc/sys/fs/binfmt_misc/register
>> +}
>> +
>> +qemu_generate_systemd() {
>> +    echo "Setting $qemu as binfmt interpreter for $cpu for
>> systemd-binfmt.service"
>> +    echo ":qemu-$cpu:M::$magic:$mask:$qemu:$FLAGS" >
>> "/etc/binfmt.d/qemu-$cpu.conf"
> 
> This is duplicating the binfmt lines. While not terrible, I think it'd
> be awesome if we could move it out into a separate function that gets
> called from the self-register and systemd-register functions.

OK

>> +}
>> +
>> +qemu_generate_packages() {
> 
> This is the debian version, right? Should be reflected in its function
> name.

OK

>> +    cat > "$EXPORTDIR/qemu-$cpu" <<!EOF
>> +package qemu-$cpu
>> +interpreter $qemu
>> +magic $magic
>> +mask $mask
>> +!EOF
>> +    if [ "$FLAGS" = "OC" ] ; then
>> +        echo "credentials yes" >> "$EXPORTDIR/qemu-$cpu"
>> +    fi
>> +}
>> +
>> +qemu_set_binfmts() {
>> +    # probe cpu type
>> +    host_family=$(qemu_get_family)
>> +
>> +    # register the interpreter for each cpu except for the native one
>> +
>> +    for cpu in ${qemu_target_list} ; do
>> +        magic=$(eval echo \$${cpu}_magic)
>> +        mask=$(eval echo \$${cpu}_mask)
>> +        family=$(eval echo \$${cpu}_family)
> 
> Debian had quite sophisticated groupings and logic to not register
> certain handlers under certain circumstances. Michael, can you please
> double-check that we're not regressing for you guys?
> 
>> +
>> +        if [ "$magic" = "" -o "$mask" = "" -o "$family" = "" ] ; then
>> +            echo "INTERNAL ERROR: unknown cpu $cpu" 1>&2
>> +            continue
>> +        fi
>> +
>> +        qemu="$QEMU_PATH/qemu-$cpu"
>> +        if [ "$cpu" = "i486" ] ; then
>> +            qemu="$QEMU_PATH/qemu-i386"
>> +        fi
>> +
>> +        if [ "$host_family" != "$family" ] ; then
>> +            $BINFMT_SET
>> +        fi
>> +    done
>> +}
>> +
>> +BINFMT_SET=qemu_register_interpreter
>> +QEMU_PATH=/usr/local/bin
>> +EXPORTDIR="/usr/share/binfmts"
>> +CHECK=qemu_check_bintfmt_misc
>> +FLAGS=""
>> +
>> +options=$(getopt -o ds:Q:e:hc: -l
>> debian,systemd:,qemu-path:,exportdir:,help,credential: -- "$@")
>> +eval set -- "$options"
>> +
>> +while true ; do
>> +    case "$1" in
>> +    -d|--debian)
>> +        CHECK=qemu_check_debian
>> +        BINFMT_SET=qemu_generate_packages
>> +        ;;
>> +    -s|--systemd)
>> +        CHECK=qemu_check_systemd
>> +        BINFMT_SET=qemu_generate_systemd
>> +        shift
>> +        qemu_target_list="$1"
>> +        ;;
>> +    -Q|--qemu-path)
>> +        shift
>> +        QEMU_PATH="$1"
>> +        ;;
>> +    -e|--exportdir)
>> +        shift
>> +        EXPORTDIR="$1"
>> +        if [ ! -d "$EXPORTDIR" ] ; then
>> +            echo "ERROR: $EXPORTDIR doesn't exist" 1>&2
>> +            exit 1
>> +        fi
>> +        ;;
>> +    -h|--help)
>> +        usage
>> +        exit 1
>> +        ;;
>> +    -c|--credential)
>> +        shift
>> +        if [ "$1" = "yes" ] ; then
>> +            FLAGS="OC"
>> +        else
>> +            FLAGS=""
>> +        fi
>> +        ;;
>> +    *)
>> +        break
>> +        ;;
>> +    esac
>> +    shift
>> +done
>> +
>> +$CHECK
>> +qemu_set_binfmts
> 
> Ah, nice, so the old behavior does get preserved. Great :)
> 
> Alex
>
diff mbox

Patch

diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
old mode 100644
new mode 100755
index 289b1a3..f34b282
--- a/scripts/qemu-binfmt-conf.sh
+++ b/scripts/qemu-binfmt-conf.sh
@@ -1,72 +1,305 @@ 
 #!/bin/sh
 # enable automatic i386/ARM/M68K/MIPS/SPARC/PPC/s390 program execution by the kernel
 
-# load the binfmt_misc module
-if [ ! -d /proc/sys/fs/binfmt_misc ]; then
-  /sbin/modprobe binfmt_misc
-fi
-if [ ! -f /proc/sys/fs/binfmt_misc/register ]; then
-  mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
-fi
-
-# probe cpu type
-cpu=`uname -m`
-case "$cpu" in
-  i386|i486|i586|i686|i86pc|BePC|x86_64)
-    cpu="i386"
-  ;;
-  m68k)
-    cpu="m68k"
-  ;;
-  mips*)
-    cpu="mips"
-  ;;
-  "Power Macintosh"|ppc|ppc64)
-    cpu="ppc"
-  ;;
-  armv[4-9]*)
-    cpu="arm"
-  ;;
-esac
-
-# register the interpreter for each cpu except for the native one
-if [ $cpu != "i386" ] ; then
-    echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
-    echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
-fi
-if [ $cpu != "alpha" ] ; then
-    echo ':alpha:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-alpha:' > /proc/sys/fs/binfmt_misc/register
-fi
-if [ $cpu != "arm" ] ; then
-    echo   ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-arm:' > /proc/sys/fs/binfmt_misc/register
-    echo   ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-armeb:' > /proc/sys/fs/binfmt_misc/register
-fi
-if [ $cpu != "aarch64" ] ; then
-    echo ':aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-aarch64:' > /proc/sys/fs/binfmt_misc/register
-fi
-if [ $cpu != "sparc" ] ; then
-    echo   ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sparc:' > /proc/sys/fs/binfmt_misc/register
-fi
-if [ $cpu != "ppc" ] ; then
-    echo   ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-ppc:' > /proc/sys/fs/binfmt_misc/register
-fi
-if [ $cpu != "m68k" ] ; then
-    echo   'Please check cpu value and header information for m68k!'
-    echo   ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-m68k:' > /proc/sys/fs/binfmt_misc/register
-fi
-if [ $cpu != "mips" ] ; then
-    # FIXME: We could use the other endianness on a MIPS host.
-    echo   ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips:' > /proc/sys/fs/binfmt_misc/register
-    echo   ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsel:' > /proc/sys/fs/binfmt_misc/register
-    echo   ':mipsn32:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mipsn32:' > /proc/sys/fs/binfmt_misc/register
-    echo   ':mipsn32el:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsn32el:' > /proc/sys/fs/binfmt_misc/register
-    echo   ':mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips64:' > /proc/sys/fs/binfmt_misc/register
-    echo   ':mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mips64el:' > /proc/sys/fs/binfmt_misc/register
-fi
-if [ $cpu != "sh" ] ; then
-    echo    ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-sh4:' > /proc/sys/fs/binfmt_misc/register
-    echo    ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sh4eb:' > /proc/sys/fs/binfmt_misc/register
-fi
-if [ $cpu != "s390x" ] ; then
-    echo   ':s390x:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-s390x:' > /proc/sys/fs/binfmt_misc/register
-fi
+qemu_target_list="i386 i486 alpha arm sparc32plus ppc ppc64 ppc64le m68k \
+                  mips mipsel mipsn32 mipsn32el mips64 mips64el \
+                  sh4 sh4eb s390x aarch64"
+
+i386_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00'
+i386_mask='\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
+i386_family=i386
+
+i486_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00'
+i486_mask='\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
+i486_family=i386
+
+alpha_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90'
+alpha_mask='\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
+alpha_family=alpha
+
+arm_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00'
+arm_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
+arm_family=arm
+
+armeb_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28'
+armeb_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+armeb_family=arm
+
+sparc_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02'
+sparc_mask='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+sparc_family=sparc
+
+sparc32plus_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x12'
+sparc32plus_mask='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+sparc32plus_family=sparc
+
+ppc_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14'
+ppc_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+ppc_family=ppc
+
+ppc64_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15'
+ppc64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+ppc64_family=ppc
+
+ppc64le_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15\x00'
+ppc64le_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\x00'
+ppc64le_family=ppc
+
+m68k_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04'
+m68k_mask='\xff\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+m68k_family=m68k
+
+# FIXME: We could use the other endianness on a MIPS host.
+
+mips_magic='\x7fELF\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+mips_family=mips
+
+mipsel_magic='\x7fELF\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\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
+mipsel_family=mips
+
+mipsn32_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08'
+mipsn32_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+mipsn32_family=mips
+
+mipsn32el_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00'
+mipsn32el_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
+mipsn32el_family=mips
+
+mips64_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08'
+mips64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+mips64_family=mips
+
+mips64el_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00'
+mips64el_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
+mips64el_family=mips
+
+sh4_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00'
+sh4_mask='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
+sh4_family=sh4
+
+sh4eb_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a'
+sh4eb_mask='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+sh4eb_family=sh4
+
+s390x_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16'
+s390x_mask='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+s390x_family=s390x
+
+aarch64_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00'
+aarch64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
+aarch64_family=aarch64
+
+qemu_get_family() {
+    cpu=$(uname -m)
+    case "$cpu" in
+    i386|i486|i586|i686|i86pc|BePC|x86_64)
+        echo "i386"
+        ;;
+    mips*)
+        echo "mips"
+        ;;
+    "Power Macintosh")
+        echo "ppc"
+        ;;
+    armv[4-9]*)
+        echo "arm"
+        ;;
+    sparc*)
+        echo "sparc"
+        ;;
+    *)
+        echo "$cpu"
+        ;;
+    esac
+}
+
+usage() {
+    cat <<!EOF
+Usage: qemu-binfmt-conf.sh [--qemu-path PATH][--debian [--exportdir PATH]]
+                           [--help][--credential yes|no][--systemd CPU]
+
+       Configure binfmt_misc to use qemu interpreter
+
+       --help:       display this usage
+       --qemu-path:  set path to qemu interpreter ($QEMU_PATH)
+       --debian:     don't write into /proc,
+                     instead generate update-binfmts templates
+       --systemd:    don't write into /proc,
+                     instead generate file for systemd-binfmt.service
+                     for the given CPU
+       --exportdir:  define where to write update-binfmts templates
+                     ($EXPORTDIR)
+       --credential: if yes, credential an security tokens are
+                     calculated according to the binary to interpret
+
+    To import templates with update-binfmts, use :
+
+        sudo update-binfmts --importdir $EXPORTDIR --import qemu-CPU
+
+    To remove interpreter, use :
+
+        sudo update-binfmts --package qemu-CPU --remove qemu-CPU $QEMU_PATH
+
+    With systemd, binfmt files are loaded by systemd-binfmt.service
+
+    where CPU is one of:
+
+!EOF
+    echo -n "    "
+    for CPU in $qemu_target_list ;
+    do
+        echo -n "$CPU "
+    done
+    echo
+}
+
+qemu_check_bintfmt_misc() {
+    # load the binfmt_misc module
+    if [ ! -d /proc/sys/fs/binfmt_misc ]; then
+      if ! /sbin/modprobe binfmt_misc ; then
+          exit 1
+      fi
+    fi
+    if [ ! -f /proc/sys/fs/binfmt_misc/register ]; then
+      if ! mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc ; then
+          exit 1
+      fi
+    fi
+
+    if [ ! -w /proc/sys/fs/binfmt_misc/register ] ; then
+        echo "ERROR: cannot write to /proc/sys/fs/binfmt_misc/register" 1>&2
+        exit 1
+    fi
+}
+
+installed_dpkg() {
+    dpkg --status "$1" > /dev/null 2>&1
+}
+
+qemu_check_debian() {
+    if [ ! -e /etc/debian_version ] ; then
+        echo "ERROR: this script works only on Debian based distro" 1>&2
+        exit 1
+    fi
+    if ! installed_dpkg binfmt-support ; then
+        echo "ERROR: package binfmt-support is needed !" 1>&2
+        exit 1
+    fi
+}
+
+qemu_check_systemd() {
+    if ! systemctl -q is-enabled systemd-binfmt.service ; then
+        echo "ERROR: systemd-binfmt.service is missing or disabled !" 1>&2
+        exit 1
+    fi
+    if [ "$UID" != "0" ] ; then
+        echo "ERROR: you must be root to be able to write systemd configuration files !" 1>&2
+        exit 1
+    fi
+}
+
+qemu_register_interpreter() {
+    echo "Setting $qemu as binfmt interpreter for $cpu"
+    echo ":qemu-$cpu:M::$magic:$mask:$qemu:$FLAGS" > /proc/sys/fs/binfmt_misc/register
+}
+
+qemu_generate_systemd() {
+    echo "Setting $qemu as binfmt interpreter for $cpu for systemd-binfmt.service"
+    echo ":qemu-$cpu:M::$magic:$mask:$qemu:$FLAGS" > "/etc/binfmt.d/qemu-$cpu.conf"
+}
+
+qemu_generate_packages() {
+    cat > "$EXPORTDIR/qemu-$cpu" <<!EOF
+package qemu-$cpu
+interpreter $qemu
+magic $magic
+mask $mask
+!EOF
+    if [ "$FLAGS" = "OC" ] ; then
+        echo "credentials yes" >> "$EXPORTDIR/qemu-$cpu"
+    fi
+}
+
+qemu_set_binfmts() {
+    # probe cpu type
+    host_family=$(qemu_get_family)
+
+    # register the interpreter for each cpu except for the native one
+
+    for cpu in ${qemu_target_list} ; do
+        magic=$(eval echo \$${cpu}_magic)
+        mask=$(eval echo \$${cpu}_mask)
+        family=$(eval echo \$${cpu}_family)
+
+        if [ "$magic" = "" -o "$mask" = "" -o "$family" = "" ] ; then
+            echo "INTERNAL ERROR: unknown cpu $cpu" 1>&2
+            continue
+        fi
+
+        qemu="$QEMU_PATH/qemu-$cpu"
+        if [ "$cpu" = "i486" ] ; then
+            qemu="$QEMU_PATH/qemu-i386"
+        fi
+
+        if [ "$host_family" != "$family" ] ; then
+            $BINFMT_SET
+        fi
+    done
+}
+
+BINFMT_SET=qemu_register_interpreter
+QEMU_PATH=/usr/local/bin
+EXPORTDIR="/usr/share/binfmts"
+CHECK=qemu_check_bintfmt_misc
+FLAGS=""
+
+options=$(getopt -o ds:Q:e:hc: -l debian,systemd:,qemu-path:,exportdir:,help,credential: -- "$@")
+eval set -- "$options"
+
+while true ; do
+    case "$1" in
+    -d|--debian)
+        CHECK=qemu_check_debian
+        BINFMT_SET=qemu_generate_packages
+        ;;
+    -s|--systemd)
+        CHECK=qemu_check_systemd
+        BINFMT_SET=qemu_generate_systemd
+        shift
+        qemu_target_list="$1"
+        ;;
+    -Q|--qemu-path)
+        shift
+        QEMU_PATH="$1"
+        ;;
+    -e|--exportdir)
+        shift
+        EXPORTDIR="$1"
+        if [ ! -d "$EXPORTDIR" ] ; then
+            echo "ERROR: $EXPORTDIR doesn't exist" 1>&2
+            exit 1
+        fi
+        ;;
+    -h|--help)
+        usage
+        exit 1
+        ;;
+    -c|--credential)
+        shift
+        if [ "$1" = "yes" ] ; then
+            FLAGS="OC"
+        else
+            FLAGS=""
+        fi
+        ;;
+    *)
+        break
+        ;;
+    esac
+    shift
+done
+
+$CHECK
+qemu_set_binfmts