* [Qemu-devel] [PATCH v2] 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.
@ 2016-01-28 22:08 Laurent Vivier
2016-01-28 22:29 ` Eric Blake
0 siblings, 1 reply; 3+ messages in thread
From: Laurent Vivier @ 2016-01-28 22:08 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, riku.voipio, mjt, agraf, Laurent Vivier
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][--systemd CPU]
[--help][--credential yes|no][--exportdir PATH]
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 configuration files
(default: /etc/binfmt.d or /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
The environment variable HOST_ARCH allows to override 'uname' to generate
configuration files for a different architecture than the current one.
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
v2: replace some ERRORS by WARNINGS to be able to use the script inside a package build
check only the right to write in the directory, no need to be root
merge systemd and binfmt_misc configuration generation
s/qemu_generate_packages/qemu_generate_debian/
add support of HOST_ARCH from debian, and update CPU families.
allow to use --exportdir with --systemd and update "Usage".
scripts/qemu-binfmt-conf.sh | 380 ++++++++++++++++++++++++++++++++++++--------
1 file changed, 311 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..56bc88e
--- a/scripts/qemu-binfmt-conf.sh
+++ b/scripts/qemu-binfmt-conf.sh
@@ -1,72 +1,314 @@
#!/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=ppcle
+
+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=arm
+
+qemu_get_family() {
+ cpu=${HOST_ARCH:-$(uname -m)}
+ case "$cpu" in
+ amd64|i386|i486|i586|i686|i86pc|BePC|x86_64)
+ echo "i386"
+ ;;
+ mips*)
+ echo "mips"
+ ;;
+ "Power Macintosh"|ppc64|powerpc|ppc)
+ echo "ppc"
+ ;;
+ ppc64el|ppc64le)
+ echo "ppcle"
+ ;;
+ arm|armel|armhf|arm64|armv[4-9]*)
+ echo "arm"
+ ;;
+ sparc*)
+ echo "sparc"
+ ;;
+ *)
+ echo "$cpu"
+ ;;
+ esac
+}
+
+usage() {
+ cat <<!EOF
+Usage: qemu-binfmt-conf.sh [--qemu-path PATH][--debian][--systemd CPU]
+ [--help][--credential yes|no][--exportdir PATH]
+
+ 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 configuration files
+ (default: $SYSTEMDDIR or $DEBIANDIR)
+ --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:-$DEBIANDIR} --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
+
+ The environment variable HOST_ARCH allows to override 'uname' to generate
+ configuration files for a different architecture than the current one.
+
+ where CPU is one of:
+
+!EOF
+ echo -n " "
+ for CPU in $qemu_target_list ;
+ do
+ echo -n "$CPU "
+ done
+ echo
+}
+
+qemu_check_access() {
+ if [ ! -w "$1" ] ; then
+ echo "ERROR: cannot write to $1" 1>&2
+ exit 1
+ fi
+}
+
+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
+
+ qemu_check_access /proc/sys/fs/binfmt_misc/register
+}
+
+installed_dpkg() {
+ dpkg --status "$1" > /dev/null 2>&1
+}
+
+qemu_check_debian() {
+ if [ ! -e /etc/debian_version ] ; then
+ echo "WARNING: your system is not a Debian based distro" 1>&2
+ elif ! installed_dpkg binfmt-support ; then
+ echo "WARNING: package binfmt-support is needed !" 1>&2
+ fi
+ qemu_check_access "$EXPORTDIR"
+}
+
+qemu_check_systemd() {
+ if ! systemctl -q is-enabled systemd-binfmt.service ; then
+ echo "WARNING: systemd-binfmt.service is missing or disabled !" 1>&2
+ fi
+ qemu_check_access "$EXPORTDIR"
+}
+
+qemu_generate_register() {
+ echo ":qemu-$cpu:M::$magic:$mask:$qemu:$FLAGS"
+}
+
+qemu_register_interpreter() {
+ echo "Setting $qemu as binfmt interpreter for $cpu"
+ qemu_generate_register > /proc/sys/fs/binfmt_misc/register
+}
+
+qemu_generate_systemd() {
+ echo "Setting $qemu as binfmt interpreter for $cpu for systemd-binfmt.service"
+ qemu_generate_register > "$EXPORTDIR/qemu-$cpu.conf"
+}
+
+qemu_generate_debian() {
+ 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
+}
+
+CHECK=qemu_check_bintfmt_misc
+BINFMT_SET=qemu_register_interpreter
+
+SYSTEMDDIR="/etc/binfmt.d"
+DEBIANDIR="/usr/share/binfmts"
+
+QEMU_PATH=/usr/local/bin
+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_debian
+ EXPORTDIR=${EXPORTDIR:-$DEBIANDIR}
+ ;;
+ -s|--systemd)
+ CHECK=qemu_check_systemd
+ BINFMT_SET=qemu_generate_systemd
+ EXPORTDIR=${EXPORTDIR:-$SYSTEMDDIR}
+ shift
+ qemu_target_list="$1"
+ ;;
+ -Q|--qemu-path)
+ shift
+ QEMU_PATH="$1"
+ ;;
+ -e|--exportdir)
+ shift
+ EXPORTDIR="$1"
+ ;;
+ -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
--
2.5.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [Qemu-devel] [PATCH v2] 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.
2016-01-28 22:08 [Qemu-devel] [PATCH v2] 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 Laurent Vivier
@ 2016-01-28 22:29 ` Eric Blake
2016-01-28 22:51 ` Laurent Vivier
0 siblings, 1 reply; 3+ messages in thread
From: Eric Blake @ 2016-01-28 22:29 UTC (permalink / raw)
To: Laurent Vivier, qemu-devel; +Cc: peter.maydell, riku.voipio, mjt, agraf
[-- Attachment #1: Type: text/plain, Size: 3707 bytes --]
On 01/28/2016 03:08 PM, Laurent Vivier wrote:
Subject line is TOOO long. I suggest:
linux-user: Fix qemu-binfmt-conf.h to store config across reboot
> 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.
>
> diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
> old mode 100644
> new mode 100755
> index 289b1a3..56bc88e
> --- a/scripts/qemu-binfmt-conf.sh
> +++ b/scripts/qemu-binfmt-conf.sh
> @@ -1,72 +1,314 @@
> #!/bin/sh
> # enable automatic i386/ARM/M68K/MIPS/SPARC/PPC/s390 program execution by the kernel
>
> +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=arm
> +
> +qemu_get_family() {
> +
> +usage() {
> + cat <<!EOF
Use of '!EOF' is an unusual heredoc delimiter; it fails miserably if
history expansion is enabled.
> +Usage: qemu-binfmt-conf.sh [--qemu-path PATH][--debian][--systemd CPU]
> + --credential: if yes, credential an security tokens are
s/an/and/
> + echo -n " "
'echo -n' is not portable. Use 'printf' instead.
> + for CPU in $qemu_target_list ;
> + do
> + echo -n "$CPU "
and again.
> + done
> + echo
This loop results in trailing whitespace (not fatal, but nice to avoid
where possible). Also, using a shell loop is a waste of effort; when
you can just do:
printf "%s " $qemu_target_list
and get the same effect.
> +}
> +
> +qemu_check_access() {
> + if [ ! -w "$1" ] ; then
> + echo "ERROR: cannot write to $1" 1>&2
> + exit 1
Checking whether a file is writable is often a TOCTTOU race; since you
have to handle failures to redirect to the file anyways (in case the
file changed between your check and the actual use), can you just skip
the check as redundant?
> +qemu_check_debian() {
> + if [ ! -e /etc/debian_version ] ; then
> + echo "WARNING: your system is not a Debian based distro" 1>&2
> + elif ! installed_dpkg binfmt-support ; then
> + echo "WARNING: package binfmt-support is needed !" 1>&2
Trailing '!' in error messages is shouting at the user; I tend to avoid
them. But if you must use it, in English there is no space between the
final word and the punctuation: s/needed !/needed!/
> + fi
> + qemu_check_access "$EXPORTDIR"
> +}
> +
> +qemu_check_systemd() {
> + if ! systemctl -q is-enabled systemd-binfmt.service ; then
> + echo "WARNING: systemd-binfmt.service is missing or disabled !" 1>&2
and again
> +qemu_generate_debian() {
> + cat > "$EXPORTDIR/qemu-$cpu" <<!EOF
> +package qemu-$cpu
Again, !EOF is an unusual delimiter.
> +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)
Use of eval is risky; fortunately, it looks like $qemu_target_list is
under your control and can't be overridden by the user's environment to
do something malicious.
> +
> + if [ "$magic" = "" -o "$mask" = "" -o "$family" = "" ] ; then
"[ ... -o ... ]" is not portable. Use "[ ... ] || [ ... ]" instead.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Qemu-devel] [PATCH v2] 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.
2016-01-28 22:29 ` Eric Blake
@ 2016-01-28 22:51 ` Laurent Vivier
0 siblings, 0 replies; 3+ messages in thread
From: Laurent Vivier @ 2016-01-28 22:51 UTC (permalink / raw)
To: Eric Blake, qemu-devel; +Cc: peter.maydell, riku.voipio, mjt, agraf
Le 28/01/2016 23:29, Eric Blake a écrit :
> On 01/28/2016 03:08 PM, Laurent Vivier wrote:
>
> Subject line is TOOO long. I suggest:
>
> linux-user: Fix qemu-binfmt-conf.h to store config across reboot
OK. I was waiting this comment ;)
>
>> 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.
>>
>
>> diff --git a/scripts/qemu-binfmt-conf.sh
>> b/scripts/qemu-binfmt-conf.sh old mode 100644 new mode 100755
>> index 289b1a3..56bc88e --- a/scripts/qemu-binfmt-conf.sh +++
>> b/scripts/qemu-binfmt-conf.sh @@ -1,72 +1,314 @@ #!/bin/sh #
>> enable automatic i386/ARM/M68K/MIPS/SPARC/PPC/s390 program
>> execution by the kernel
>>
>
>> +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=arm + +qemu_get_family() {
>
>> + +usage() { + cat <<!EOF
>
> Use of '!EOF' is an unusual heredoc delimiter; it fails miserably
> if history expansion is enabled.
Well, I've learned that on HP-UX 10.20 (in '90s), so I'm not surprised
it could have some troubles now. I will change that.
>> +Usage: qemu-binfmt-conf.sh [--qemu-path
>> PATH][--debian][--systemd CPU]
>
>> + --credential: if yes, credential an security tokens are
>
> s/an/and/
OK
>
>> + echo -n " "
>
> 'echo -n' is not portable. Use 'printf' instead.
OK
>
>> + for CPU in $qemu_target_list ; + do + echo -n
>> "$CPU "
>
> and again.
OK
>> + done + echo
>
> This loop results in trailing whitespace (not fatal, but nice to
> avoid where possible). Also, using a shell loop is a waste of
> effort; when you can just do:
>
> printf "%s " $qemu_target_list
>
> and get the same effect.
OK
>> +} + +qemu_check_access() { + if [ ! -w "$1" ] ; then +
>> echo "ERROR: cannot write to $1" 1>&2 + exit 1
>
> Checking whether a file is writable is often a TOCTTOU race; since
> you have to handle failures to redirect to the file anyways (in
> case the file changed between your check and the actual use), can
> you just skip the check as redundant?
Checking right access allows to know if the system supports
binfmt_misc, debian packages or systemd, and if we can write here (are
we root ?, see Alex comment), so this check is really needed here. No
need to care of TOCTTOU.
>
>
>> +qemu_check_debian() { + if [ ! -e /etc/debian_version ] ;
>> then + echo "WARNING: your system is not a Debian based
>> distro" 1>&2 + elif ! installed_dpkg binfmt-support ; then +
>> echo "WARNING: package binfmt-support is needed !" 1>&2
>
> Trailing '!' in error messages is shouting at the user; I tend to
> avoid them. But if you must use it, in English there is no space
> between the final word and the punctuation: s/needed !/needed!/
Yes, I often forget French and English differ in the use of
punctuation. :)
I will remove the '!'.
>
>> + fi + qemu_check_access "$EXPORTDIR" +} +
>> +qemu_check_systemd() { + if ! systemctl -q is-enabled
>> systemd-binfmt.service ; then + echo "WARNING:
>> systemd-binfmt.service is missing or disabled !" 1>&2
>
> and again
OK
>> +qemu_generate_debian() { + cat > "$EXPORTDIR/qemu-$cpu"
>> <<!EOF +package qemu-$cpu
>
> Again, !EOF is an unusual delimiter.
OK
>
>> +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)
>
> Use of eval is risky; fortunately, it looks like $qemu_target_list
> is under your control and can't be overridden by the user's
> environment to do something malicious.
>
>> + + if [ "$magic" = "" -o "$mask" = "" -o "$family" = "" ]
>> ; then
>
> "[ ... -o ... ]" is not portable. Use "[ ... ] || [ ... ]"
> instead.
OK
Thank you!
Laurent
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2016-01-28 22:52 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-01-28 22:08 [Qemu-devel] [PATCH v2] 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 Laurent Vivier
2016-01-28 22:29 ` Eric Blake
2016-01-28 22:51 ` Laurent Vivier
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).