@@ -6,6 +6,32 @@ mips mipsel mipsn32 mipsn32el mips64 mips64el \
sh4 sh4eb s390x aarch64 aarch64_be hppa riscv32 riscv64 xtensa xtensaeb \
microblaze microblazeel or1k x86_64"
+# check if given target CPUS is/are in the supported target list
+qemu_check_target_list() {
+ all="$qemu_target_list"
+ if [ "$1" = "ALL" ]; then
+ checked_target_list="$all"
+ return
+ fi
+ list=""
+ for target in $@; do
+ unknown_target="true"
+ for cpu in $all ; do
+ if [ "$cpu" = "$target" ] ; then
+ list="$list $target"
+ unknown_target="false"
+ break
+ fi
+ done
+ if [ "$unknown_target" = "true" ] ; then
+ echo "ERROR: unknown CPU \"$target\"" 1>&2
+ usage
+ exit 1
+ fi
+ done
+ checked_target_list="$list"
+}
+
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\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
i386_family=i386
@@ -167,45 +193,48 @@ qemu_get_family() {
usage() {
cat <<EOF
-Usage: qemu-binfmt-conf.sh [--qemu-path PATH][--debian][--systemd CPU]
- [--help][--credential yes|no][--exportdir PATH]
- [--persistent yes|no][--qemu-suffix SUFFIX]
-
- Configure binfmt_misc to use qemu interpreter
-
- --help: display this usage
- --qemu-path: set path to qemu interpreter ($QEMU_PATH)
- --qemu-suffix: add a suffix to the default interpreter name
- --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. If CPU is "ALL", generate a
- file for all known cpus
- --exportdir: define where to write configuration files
- (default: $SYSTEMDDIR or $DEBIANDIR)
- --credential: if yes, credential and security tokens are
- calculated according to the binary to interpret
- --persistent: if yes, the interpreter is loaded when binfmt is
- configured and remains in memory. All future uses
- are cloned from the open file.
-
- 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:
-
- $qemu_target_list
+Usage: qemu-binfmt-conf.sh [--help][--qemu-path PATH][--qemu-suffix SUFFIX]
+ [--persistent][--credential][--exportdir PATH]
+ [--reset ARCHS][--systemd][--debian][CPUS]
+
+ Configure binfmt_misc to use qemu interpreter for the given target CPUS.
+ Supported formats for CPUS are: single arch or comma/space separated list.
+ If CPUS is empty, configure all known cpus. See QEMU target list below.
+
+ --help: display this usage.
+ --qemu-path: set path to qemu interpreter ($QEMU_PATH).
+ --qemu-suffix: add a suffix to the default interpreter name.
+ --persistent: if present, the interpreter is loaded when binfmt is
+ configured and remains in memory. All future uses
+ are cloned from the open file.
+ --credential: if present, credential and security tokens are
+ calculated according to the binary to interpret.
+ --exportdir: define where to write configuration files
+ (default: $SYSTEMDDIR or $DEBIANDIR).
+ --reset: remove registered interpreter for target ARCHS (comma
+ separated list). If ARCHS is 'ALL', remove all registered
+ 'qemu-*' interpreters.
+ --systemd: don't write into /proc,
+ instead generate file(s) for systemd-binfmt.service;
+ environment variable HOST_ARCH allows to override 'uname'
+ to generate configuration files for a different
+ architecture than the current one.
+ --debian: don't write into /proc,
+ instead generate update-binfmts templates.
+
+ 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
+
+ QEMU target list: $qemu_target_list
EOF
}
@@ -286,12 +315,22 @@ EOF
}
qemu_set_binfmts() {
+ if [ "$1" = "NONE" ]; then
+ return
+ fi
+
# probe cpu type
host_family=$(qemu_get_family)
- # register the interpreter for each cpu except for the native one
+ # reduce the list of target interpreters to those given in the CLI
+ targets="$@"
+ if [ $# -eq 0 ]; then
+ targets="ALL"
+ fi
+ qemu_check_target_list $(echo "$targets" | tr ',' ' ')
- for cpu in ${qemu_target_list} ; do
+ # register the interpreter for each target except for the native one
+ for cpu in $checked_target_list; do
magic=$(eval echo \$${cpu}_magic)
mask=$(eval echo \$${cpu}_mask)
family=$(eval echo \$${cpu}_family)
@@ -313,8 +352,26 @@ qemu_set_binfmts() {
done
}
+qemu_remove_notimplemented() {
+ echo "ERROR: option reset not implemented for this mode yet" 1>&2
+ usage
+ exit 1
+}
+
+qemu_remove_interpreter() {
+ if [ "$1" = "ALL" ]; then
+ find /proc/sys/fs/binfmt_misc/ -type f -name 'qemu-*' -exec sh -c
'echo -1 > {}' \;
+ else
+ qemu_check_target_list $(echo "$1" | tr ',' ' ')
+ for t in $checked_target_list; do
+ find /proc/sys/fs/binfmt_misc/ -type f -name "qemu-$t" -exec sh -c
'echo -1 > {}' \;
+ done
+ fi
+}
+
CHECK=qemu_check_bintfmt_misc
BINFMT_SET=qemu_register_interpreter
+BINFMT_REMOVE=qemu_remove_interpreter
I'm so sorry for the inconvenience of sending this patch multiple times. This is my first contribution through email, and I am having a hard time preventing the client from mangling with it. This time, I attached que body below too. I hope that this allows any other to properly push it, in case it is still not picked by patchew. Related to https://bugs.launchpad.net/qemu/+bug/1817239 - Positional parameters are supported as [CPUS]. This can be a single target arch, a comma separated list or a space separated list. This parameter replaces qemu_target_list for any mode (default, systemd or debian). If it is left empty or ALL is provided, all the targets are registered. If NONE is provided, no target is registered. - Option [--systemd CPU] is modified to [--systemd], since the functionality is supported by [CPUS] now. - [--credential yes|no] and [--persistent yes|no] are modified to [--credential] and [--persistent], respectively. They are 'no' by default, and 'yes' if the corresponding flag is provided. - [--reset ARCHS] is added. This allows to remove registered interpreters. Supported formats are a single target name or a comma separated list of targets. If ALL is provided, all the existing 'qemu-*' interpreters are removed. - 'usage' is updated according to the changes above. Note that I don't know how to proceed when `--reset` is used together with `--systemd` or `--debian`. At the moment, if `--reset` is provided first, both options are used, one after the other. However, if any of the other two is provided first, a error is shown: 'option reset not implemented for this mode yet'. Some example use cases that are to be supported by this patch: qemu-binfmt-conf.sh -p aarch64 qemu-binfmt-conf.sh -p aarch64 riscv64 qemu-binfmt-conf.sh -p aarch64,riscv64 qemu-binfmt-conf.sh -r ALL -p aarch64 qemu-binfmt-conf.sh -r aarch64 -p aarch64 qemu-binfmt-conf.sh -r ALL -p aarch64 riscv64 qemu-binfmt-conf.sh -r ALL -p aarch64,riscv64 qemu-binfmt-conf.sh -r aarch64,riscv64 -p aarch64 riscv64 qemu-binfmt-conf.sh -r aarch64,riscv64 -p aarch64,riscv64 qemu-binfmt-conf.sh -r ALL NONE The main purpose of these changes is to make it easier to use qemu-user-static to build docker images for foreign architectures. See https://github.com/umarcor/qus/tree/qemu-update Signed-off-by: Unai Martinez-Corral <unai.martinezcorral@ehu.eus> --- scripts/qemu-binfmt-conf.sh | 174 +++++++++++++++++++++++------------- 1 file changed, 110 insertions(+), 64 deletions(-) SYSTEMDDIR="/etc/binfmt.d" DEBIANDIR="/usr/share/binfmts" @@ -324,37 +381,26 @@ CREDENTIAL=no PERSISTENT=no QEMU_SUFFIX="" -options=$(getopt -o ds:Q:S:e:hc:p: -l debian,systemd:,qemu-path:,qemu-suffix:,exportdir:,help,credential:,persistent: -- "$@") +options=$(getopt -o r:dsQ:S:e:hcp -l reset:,debian,systemd,qemu-path:,qemu-suffix:,exportdir:,help,credential,persistent -- "$@") eval set -- "$options" while true ; do case "$1" in + -r|--reset) + shift + qemu_remove_interpreter $1 + ;; -d|--debian) CHECK=qemu_check_debian BINFMT_SET=qemu_generate_debian + BINFMT_REMOVE=qemu_remove_notimplemented EXPORTDIR=${EXPORTDIR:-$DEBIANDIR} ;; -s|--systemd) CHECK=qemu_check_systemd BINFMT_SET=qemu_generate_systemd + BINFMT_REMOVE=qemu_remove_notimplemented EXPORTDIR=${EXPORTDIR:-$SYSTEMDDIR} - shift - # check given cpu is in the supported CPU list - if [ "$1" != "ALL" ] ; then - for cpu in ${qemu_target_list} ; do - if [ "$cpu" = "$1" ] ; then - break - fi - done - - if [ "$cpu" = "$1" ] ; then - qemu_target_list="$1" - else - echo "ERROR: unknown CPU \"$1\"" 1>&2 - usage - exit 1 - fi - fi ;; -Q|--qemu-path) shift @@ -373,12 +419,10 @@ while true ; do exit 1 ;; -c|--credential) - shift - CREDENTIAL="$1" + CREDENTIAL=yes ;; -p|--persistent) - shift - PERSISTENT="$1" + PERSISTENT=yes ;; *) break @@ -387,5 +431,7 @@ while true ; do shift done +shift + $CHECK -qemu_set_binfmts +qemu_set_binfmts $@ -- 2.20.1