From 7f406df8c72679712447e0a35245de58138dc494 Mon Sep 17 00:00:00 2001 From: William Hubbs Date: Tue, 31 Mar 2015 12:48:45 -0500 Subject: [PATCH] Fix binfmt processing This makes binfmt processing behave like tmpfiles processing which follows the same specification as systemd. X-Gentoo-Bug: 545162 X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=545162 --- init.d/procfs.in | 9 +----- sh/Makefile | 6 ++-- sh/binfmt.sh.in | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 11 deletions(-) create mode 100644 sh/binfmt.sh.in diff --git a/init.d/procfs.in b/init.d/procfs.in index 636cd20..98e0f54 100644 --- a/init.d/procfs.in +++ b/init.d/procfs.in @@ -27,15 +27,8 @@ start() mount -t binfmt_misc -o nodev,noexec,nosuid \ binfmt_misc /proc/sys/fs/binfmt_misc if eend $? ; then - local fmts ebegin "Loading custom binary format handlers" - fmts=$(grep -hsv -e '^[#;]' -e '^[[:space:]]*$' \ - /run/binfmt.d/*.conf \ - /etc/binfmt.d/*.conf \ - ""/usr/lib/binfmt.d/*.conf) - if [ -n "${fmts}" ]; then - echo "${fmts}" > /proc/sys/fs/binfmt_misc/register - fi + "$RC_LIBEXECDIR"/sh/binfmt.sh eend $? fi fi diff --git a/sh/Makefile b/sh/Makefile index c1953f3..8f742dc 100644 --- a/sh/Makefile +++ b/sh/Makefile @@ -12,9 +12,9 @@ include ${MK}/os.mk SRCS-FreeBSD= BIN-FreeBSD= -SRCS-Linux= cgroup-release-agent.sh.in init-early.sh.in migrate-to-run.sh.in \ - rc-cgroup.sh.in -BIN-Linux= cgroup-release-agent.sh init-early.sh migrate-to-run.sh \ +SRCS-Linux= binfmt.sh.in cgroup-release-agent.sh.in init-early.sh.in \ + migrate-to-run.sh.in rc-cgroup.sh.in +BIN-Linux= binfmt.sh cgroup-release-agent.sh init-early.sh migrate-to-run.sh \ rc-cgroup.sh SRCS-NetBSD= diff --git a/sh/binfmt.sh.in b/sh/binfmt.sh.in new file mode 100644 index 0000000..2d2d6ef --- /dev/null +++ b/sh/binfmt.sh.in @@ -0,0 +1,85 @@ +#!/bin/sh +# This is a reimplementation of the systemd binfmt.d code to register +# misc binary formats with the kernel. +# +# Copyright (c) 2015 William Hubbs +# Released under the 2-clause BSD license. +# +# See the binfmt.d manpage as well: +# http://0pointer.de/public/systemd-man/binfmt.d.html +# This script should match the manpage as of 2015/03/31 +# + +warn_invalid() { + printf "binfmt: invalid entry on line %d of \`%s'\n" "$LINENUM" "$FILE" + error=$(( error+1 )) +} >&2 + +# parse the command line +while [ $# -gt 0 ]; do + case $1 in + --verbose) VERBOSE=1 ;; + --dryrun|--dry-run) DRYRUN=1 ;; + esac + shift +done + +error=0 LINENUM=0 + +# The hardcoding of these paths is intentional; we are following the +# systemd spec. +binfmt_dirs='/usr/lib/binfmt.d/ /run/binfmt.d/ /etc/binfmt.d/' +binfmt_basenames='' +binfmt_d='' +# Build a list of sorted unique basenames +# directories declared later in the binfmt_d list will override earlier +# directories, on a per file basename basis. +# `/run/binfmt.d/foo.conf' supersedes `/usr/lib/binfmt.d/foo.conf'. +# `/run/binfmt.d/foo.conf' will always be read after `/etc/binfmt.d/bar.conf' +for d in ${binfmt_dirs} ; do + [ -d $d ] && for f in ${d}/*.conf ; do + case "${f##*/}" in + systemd.conf|systemd-*.conf) continue;; + esac + [ -f $f ] && binfmt_basenames="${binfmt_basenames}\n${f##*/}" + done # for f in ${d} +done # for d in ${binfmt_dirs} +binfmt_basenames="$(printf "${binfmt_basenames}\n" | sort -u )" + +for b in $binfmt_basenames ; do + real_f='' + for d in $binfmt_dirs ; do + f=${d}/${b} + [ -f "${f}" ] && real_f=$f + done + [ -f "${real_f}" ] && binfmt_d="${binfmt_d} ${real_f}" +done + +# loop through the gathered fragments, sorted globally by filename. +# `/run/binfmt.d/foo.conf' will always be read after `/etc/binfmt.d/bar.conf' +for FILE in $binfmt_d ; do + LINENUM=0 + + ### FILE FORMAT ### + # See https://www.kernel.org/doc/Documentation/binfmt_misc.txt + + while read line; do + LINENUM=$(( LINENUM+1 )) + + case $line in + \#*) continue ;; + \;*) continue ;; + esac + + [ -n "$VERBOSE" -o -n "$DRYRUN" ]] && echo $line + [ -z "$DRYRUN" ] && echo "${line}" > /proc/sys/fs/binfmt_misc/register + rc=$? + if [ -z "${DRYRUN}" ]; then + [ $rc -ne 0 ] && warn_invalid + fi + done <$FILE +done + +exit $error + +# vim: set ts=2 sw=2 sts=2 noet ft=sh: -- 2.0.5