This is a partial implementation.
Allows to remove a single or a list of already registered binfmt
interpreters. Valid values are those in qemu_target_list.
If TARGETS is empty, all the existing 'qemu-*' interpreters are
removed.
This is partial because 'debian' and 'systemd' configurations are not
supported. The script will exit with error 'option clear not
implemented for this mode yet'.
Removal is done by printing '-1' as explained at:
https://www.kernel.org/doc/Documentation/admin-guide/binfmt-misc.rst
Signed-off-by: Unai Martinez-Corral <unai.martinezcorral@ehu.eus>
---
scripts/qemu-binfmt-conf.sh | 41 ++++++++++++++++++++++++++++++++++---
1 file changed, 38 insertions(+), 3 deletions(-)
diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
index fde78517ff..07d1ee1f04 100755
--- a/scripts/qemu-binfmt-conf.sh
+++ b/scripts/qemu-binfmt-conf.sh
@@ -196,7 +196,7 @@ Options and associated environment variables:
Argument Env-variable Description
TARGETS QEMU_TARGETS A single arch name or a list of them (see all names below);
- if empty, configure all known targets;
+ if empty, configure/clear all known targets;
if 'NONE', no interpreter is configured.
-h|--help display this usage
-Q|--path PATH: QEMU_PATH set path to qemu interpreter(s)
@@ -206,9 +206,10 @@ TARGETS QEMU_TARGETS A single arch name or a list of them (see
systemd-binfmt.service; environment variable HOST_ARCH
allows to override 'uname' to generate configuration files
for a different architecture than the current one.
-
-e|--exportdir PATH: DEBIANDIR define where to write configuration files
SYSTEMDDIR
+-c|--clear: QEMU_CLEAR (yes) remove registered interpreters for target TARGETS;
+ then exit.
-c|--credential: QEMU_CREDENTIAL (yes) credential and security tokens are calculated according
to the binary to interpret
-p|--persistent: QEMU_PERSISTENT (yes) load the interpreter and keep it in memory; all future
@@ -336,6 +337,25 @@ qemu_set_binfmts() {
done
}
+qemu_clear_notimplemented() {
+ echo "ERROR: option clear not implemented for this mode yet" 1>&2
+ usage
+ exit 1
+}
+
+qemu_clear_interpreter() {
+ names='qemu-*'
+ if [ $# -ne 0 ] ; then
+ qemu_check_target_list $1
+ unset names pre
+ for t in $checked_target_list ; do
+ names="${names}${pre}qemu-$t"
+ pre=' -o -name '
+ done
+ fi
+ find /proc/sys/fs/binfmt_misc/ -type f -name $names -exec sh -c 'printf %s -1 > {}' \;
+}
+
CHECK=qemu_check_bintfmt_misc
BINFMT_SET=qemu_register_interpreter
@@ -347,12 +367,16 @@ QEMU_PATH="${QEMU_PATH:-/usr/local/bin}"
QEMU_SUFFIX="${QEMU_SUFFIX:-}"
QEMU_CREDENTIAL="${QEMU_CREDENTIAL:-no}"
QEMU_PERSISTENT="${QEMU_PERSISTENT:-no}"
+QEMU_CLEAR="${QEMU_CLEAR:-no}"
-options=$(getopt -o dsQ:S:e:hcp -l debian,systemd,path:,suffix:,exportdir:,help,credential,persistent -- "$@")
+options=$(getopt -o cdsQ:S:e:hcp -l clear,debian,systemd,path:,suffix:,exportdir:,help,credential,persistent -- "$@")
eval set -- "$options"
while true ; do
case "$1" in
+ -c|--clear)
+ QEMU_CLEAR="yes"
+ ;;
-d|--debian)
CHECK=qemu_check_debian
BINFMT_SET=qemu_generate_debian
@@ -395,4 +419,15 @@ done
shift
$CHECK
+
+if [ "x$QEMU_CLEAR" = "xyes" ] ; then
+ case "$BINFMT_SET" in
+ *debian) BINFMT_CLEAR=qemu_clear_notimplemented ;;
+ *systemd) BINFMT_CLEAR=qemu_clear_notimplemented ;;
+ *) BINFMT_CLEAR=qemu_clear_interpreter
+ esac
+ $BINFMT_CLEAR "$@"
+ exit
+fi
+
qemu_set_binfmts "$@"
--
2.21.0
On 11/03/2019 11:31, Unai Martinez-Corral wrote: > This is a partial implementation. > > Allows to remove a single or a list of already registered binfmt > interpreters. Valid values are those in qemu_target_list. > If TARGETS is empty, all the existing 'qemu-*' interpreters are > removed. > > This is partial because 'debian' and 'systemd' configurations are not > supported. The script will exit with error 'option clear not > implemented for this mode yet'. > > Removal is done by printing '-1' as explained at: > https://www.kernel.org/doc/Documentation/admin-guide/binfmt-misc.rst > > Signed-off-by: Unai Martinez-Corral <unai.martinezcorral@ehu.eus> > --- > scripts/qemu-binfmt-conf.sh | 41 ++++++++++++++++++++++++++++++++++--- > 1 file changed, 38 insertions(+), 3 deletions(-) > > diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh > index fde78517ff..07d1ee1f04 100755 > --- a/scripts/qemu-binfmt-conf.sh > +++ b/scripts/qemu-binfmt-conf.sh > @@ -196,7 +196,7 @@ Options and associated environment variables: > > Argument Env-variable Description > TARGETS QEMU_TARGETS A single arch name or a list of them (see all names below); > - if empty, configure all known targets; > + if empty, configure/clear all known targets; > if 'NONE', no interpreter is configured. > -h|--help display this usage > -Q|--path PATH: QEMU_PATH set path to qemu interpreter(s) > @@ -206,9 +206,10 @@ TARGETS QEMU_TARGETS A single arch name or a list of them (see > systemd-binfmt.service; environment variable HOST_ARCH > allows to override 'uname' to generate configuration files > for a different architecture than the current one. > - > -e|--exportdir PATH: DEBIANDIR define where to write configuration files > SYSTEMDDIR > +-c|--clear: QEMU_CLEAR (yes) remove registered interpreters for target TARGETS; > + then exit. > -c|--credential: QEMU_CREDENTIAL (yes) credential and security tokens are calculated according > to the binary to interpret > -p|--persistent: QEMU_PERSISTENT (yes) load the interpreter and keep it in memory; all future > @@ -336,6 +337,25 @@ qemu_set_binfmts() { > done > } > > +qemu_clear_notimplemented() { > + echo "ERROR: option clear not implemented for this mode yet" 1>&2 > + usage > + exit 1 > +} > + > +qemu_clear_interpreter() { > + names='qemu-*' > + if [ $# -ne 0 ] ; then > + qemu_check_target_list $1 > + unset names pre > + for t in $checked_target_list ; do > + names="${names}${pre}qemu-$t" > + pre=' -o -name ' > + done > + fi > + find /proc/sys/fs/binfmt_misc/ -type f -name $names -exec sh -c 'printf %s -1 > {}' \; The qemu-* will be expanded here if you have a qemu-XXX in the current directory. You must use "$names". But: To remove all, you can do: sh -c 'printf %s -1 > /proc/sys/fs/binfmt_misc/status' so something like if [ $# -eq 0 ] ; then sh -c 'printf %s -1 > /proc/sys/fs/binfmt_misc/status fi qemu_check_target_list $1 for t in $checked_target_list ; do sh -c 'printf %s -1 > /proc/sys/fs/binfmt_misc/qemu-$t' done But I think you should also taking care of the suffix. > +} > + > CHECK=qemu_check_bintfmt_misc > BINFMT_SET=qemu_register_interpreter > > @@ -347,12 +367,16 @@ QEMU_PATH="${QEMU_PATH:-/usr/local/bin}" > QEMU_SUFFIX="${QEMU_SUFFIX:-}" > QEMU_CREDENTIAL="${QEMU_CREDENTIAL:-no}" > QEMU_PERSISTENT="${QEMU_PERSISTENT:-no}" > +QEMU_CLEAR="${QEMU_CLEAR:-no}" > > -options=$(getopt -o dsQ:S:e:hcp -l debian,systemd,path:,suffix:,exportdir:,help,credential,persistent -- "$@") > +options=$(getopt -o cdsQ:S:e:hcp -l clear,debian,systemd,path:,suffix:,exportdir:,help,credential,persistent -- "$@") > eval set -- "$options" > > while true ; do > case "$1" in > + -c|--clear) > + QEMU_CLEAR="yes" > + ;; > -d|--debian) > CHECK=qemu_check_debian > BINFMT_SET=qemu_generate_debian > @@ -395,4 +419,15 @@ done > shift > > $CHECK > + > +if [ "x$QEMU_CLEAR" = "xyes" ] ; then > + case "$BINFMT_SET" in > + *debian) BINFMT_CLEAR=qemu_clear_notimplemented ;; > + *systemd) BINFMT_CLEAR=qemu_clear_notimplemented ;; > + *) BINFMT_CLEAR=qemu_clear_interpreter > + esac Put this in the previous case for decoding options, please. > + $BINFMT_CLEAR "$@" > + exit > +fi > + > qemu_set_binfmts "$@" > -- > 2.21.0 >
2019/3/11 12:04, Laurent Vivier: > > + find /proc/sys/fs/binfmt_misc/ -type f -name $names -exec sh -c 'printf %s -1 > {}' \; > > The qemu-* will be expanded here if you have a qemu-XXX in the current > directory. You must use "$names". You are correct. Indeed, I had not spotted it because I introduced a bug when renaming 'reset' to 'clear'. Precisely, '-c' was being used twice: for 'credential' and for 'clear'. Both issues will be fixed in the next version. > But: > > To remove all, you can do: > sh -c 'printf %s -1 > /proc/sys/fs/binfmt_misc/status' > > so something like > > if [ $# -eq 0 ] ; then > sh -c 'printf %s -1 > /proc/sys/fs/binfmt_misc/status > fi > qemu_check_target_list $1 > for t in $checked_target_list ; do > sh -c 'printf %s -1 > /proc/sys/fs/binfmt_misc/qemu-$t' > done Wouldn't writing to 'status' remove all the interpreters, and not only those that correspond to qemu? > But I think you should also taking care of the suffix. I think that the suffix is not related to the entry in '/proc/sys/fs/binfmt_misc/'. See, e.g.: package qemu-$cpu interpreter $qemu So, independently of which is the executable (interpreter), the package name does not include the suffix. > > +if [ "x$QEMU_CLEAR" = "xyes" ] ; then > > + case "$BINFMT_SET" in > > + *debian) BINFMT_CLEAR=qemu_clear_notimplemented ;; > > + *systemd) BINFMT_CLEAR=qemu_clear_notimplemented ;; > > + *) BINFMT_CLEAR=qemu_clear_interpreter > > + esac > > Put this in the previous case for decoding options, please. It won't work. This if/case block requires all the options to be already parsed and processed. If I put it in the case for '-r|--clear' above, it will only work only when '-r' is given after '--debian' or '--systemd'. Otherwise, BINFMT_SET will always be qemu_register_interpreter when '-crear' is evaluated. I think that we should not rely on the users providing the options in a specific order. Regards, Unai
On 11/03/2019 14:19, Unai Martinez Corral wrote: > 2019/3/11 12:04, Laurent Vivier: >>> + find /proc/sys/fs/binfmt_misc/ -type f -name $names -exec sh -c 'printf %s -1 > {}' \; >> >> The qemu-* will be expanded here if you have a qemu-XXX in the current >> directory. You must use "$names". > > You are correct. Indeed, I had not spotted it because I introduced a > bug when renaming 'reset' to 'clear'. Precisely, '-c' was being used > twice: for 'credential' and for 'clear'. Both issues will be fixed in > the next version. > >> But: >> >> To remove all, you can do: >> sh -c 'printf %s -1 > /proc/sys/fs/binfmt_misc/status' >> >> so something like >> >> if [ $# -eq 0 ] ; then >> sh -c 'printf %s -1 > /proc/sys/fs/binfmt_misc/status >> fi >> qemu_check_target_list $1 >> for t in $checked_target_list ; do >> sh -c 'printf %s -1 > /proc/sys/fs/binfmt_misc/qemu-$t' >> done > > Wouldn't writing to 'status' remove all the interpreters, and not only > those that correspond to qemu? Yes, you are right. > >> But I think you should also taking care of the suffix. > > I think that the suffix is not related to the entry in > '/proc/sys/fs/binfmt_misc/'. See, e.g.: > > package qemu-$cpu > interpreter $qemu > > So, independently of which is the executable (interpreter), the > package name does not include the suffix. Yes, you are right. >>> +if [ "x$QEMU_CLEAR" = "xyes" ] ; then >>> + case "$BINFMT_SET" in >>> + *debian) BINFMT_CLEAR=qemu_clear_notimplemented ;; >>> + *systemd) BINFMT_CLEAR=qemu_clear_notimplemented ;; >>> + *) BINFMT_CLEAR=qemu_clear_interpreter >>> + esac >> >> Put this in the previous case for decoding options, please. > > It won't work. This if/case block requires all the options to be > already parsed and processed. If I put it in the case for '-r|--clear' > above, it will only work only when '-r' is given after '--debian' or > '--systemd'. Otherwise, BINFMT_SET will always be > qemu_register_interpreter when '-crear' is evaluated. I think that we > should not rely on the users providing the options in a specific > order. I meant something like this: diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh index b5a16742a149..5c2651a6df57 100755 --- a/scripts/qemu-binfmt-conf.sh +++ b/scripts/qemu-binfmt-conf.sh @@ -327,17 +327,23 @@ QEMU_SUFFIX="" options=$(getopt -o ds:Q:S:e:hc:p: -l debian,systemd:,qemu-path:,qemu-suffix:,exportdir:,help,credential:,persistent: -- "$@") eval set -- "$options" +BINFMT_CLEAR=qemu_clear_interpreter while true ; do case "$1" in + -c|--clear) + QEMU_CLEAR="yes" + ;; -d|--debian) CHECK=qemu_check_debian BINFMT_SET=qemu_generate_debian EXPORTDIR=${EXPORTDIR:-$DEBIANDIR} + BINFMT_CLEAR=qemu_clear_notimplemented ;; -s|--systemd) CHECK=qemu_check_systemd BINFMT_SET=qemu_generate_systemd EXPORTDIR=${EXPORTDIR:-$SYSTEMDDIR} + BINFMT_CLEAR=qemu_clear_notimplemented shift # check given cpu is in the supported CPU list if [ "$1" != "ALL" ] ; then @@ -387,5 +393,9 @@ while true ; do shift done +if [ "x$QEMU_CLEAR" = "xyes" ] ; then + $BINFMT_CLEAR "$@" + exit +fi $CHECK qemu_set_binfmts
© 2016 - 2025 Red Hat, Inc.