commit:     ee1768a419122d288256cce1723d4997bd965eab
Author:     William Hubbs <w.d.hubbs <AT> gmail <DOT> com>
AuthorDate: Tue Mar 31 17:48:45 2015 +0000
Commit:     William Hubbs <williamh <AT> gentoo <DOT> org>
CommitDate: Mon Apr 20 22:10:07 2015 +0000
URL:        https://gitweb.gentoo.org/proj/openrc.git/commit/?id=ee1768a4

Add binfmt service to sysinit runlevel

This makes binfmt processing behave like tmpfiles processing which
follows the same specification as systemd.

This fixes #48.

X-Gentoo-Bug: 545162
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=545162

 init.d/Makefile    |  2 +-
 init.d/binfmt.in   | 20 +++++++++++++
 init.d/procfs.in   | 13 +--------
 runlevels/Makefile |  3 +-
 sh/.gitignore      |  1 +
 sh/Makefile        |  6 ++--
 sh/binfmt.sh.in    | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 113 insertions(+), 17 deletions(-)

diff --git a/init.d/Makefile b/init.d/Makefile
index 85925b1..0bd3651 100644
--- a/init.d/Makefile
+++ b/init.d/Makefile
@@ -21,7 +21,7 @@ SRCS-FreeBSD= hostid.in moused.in newsyslog.in pf.in rarpd.in 
rc-enabled.in \
 SRCS-FreeBSD+= adjkerntz.in devd.in dumpon.in encswap.in ipfw.in \
                mixer.in nscd.in powerd.in syscons.in
 
-SRCS-Linux=    devfs.in dmesg.in hwclock.in consolefont.in keymaps.in \
+SRCS-Linux=    binfmt.in devfs.in dmesg.in hwclock.in consolefont.in 
keymaps.in \
                killprocs.in modules.in mount-ro.in mtab.in numlock.in \
                procfs.in sysfs.in termencoding.in tmpfiles.dev.in
 

diff --git a/init.d/binfmt.in b/init.d/binfmt.in
new file mode 100644
index 0000000..651b131
--- /dev/null
+++ b/init.d/binfmt.in
@@ -0,0 +1,20 @@
+#!@SBINDIR@/openrc-run
+# Copyright 2015 William Hubbs <w.d.hu...@gmail.com>
+# Released under the 2-clause BSD license.
+
+description="Register misc binary format handlers"
+
+depend()
+{
+       after procfs
+       use modules devfs
+       keyword -openvz -prefix -vserver -lxc
+}
+
+start()
+{
+       ebegin "Loading custom binary format handlers"
+       "$RC_LIBEXECDIR"/sh/binfmt.sh
+       eend $?
+return 0
+}

diff --git a/init.d/procfs.in b/init.d/procfs.in
index dfe58cb..167a1aa 100644
--- a/init.d/procfs.in
+++ b/init.d/procfs.in
@@ -15,24 +15,13 @@ start()
 {
        # Setup Kernel Support for miscellaneous Binary Formats
        if [ -d /proc/sys/fs/binfmt_misc -a ! -e 
/proc/sys/fs/binfmt_misc/register ]; then
+               modprobe -q binfmt-misc
                if grep -qs binfmt_misc /proc/filesystems; then
                        ebegin "Mounting misc binary format filesystem"
                        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
                                eend $?
-                       fi
                fi
        fi
-
        return 0
 }

diff --git a/runlevels/Makefile b/runlevels/Makefile
index 25e3e1a..682d6e1 100644
--- a/runlevels/Makefile
+++ b/runlevels/Makefile
@@ -34,7 +34,8 @@ BOOT-FreeBSD+=        hostid newsyslog savecore syslogd
 # FreeBSD specific stuff
 BOOT-FreeBSD+= adjkerntz dumpon syscons
 
-BOOT-Linux+=   hwclock keymaps modules mtab procfs termencoding tmpfiles.setup
+BOOT-Linux+=   binfmt hwclock keymaps modules mtab procfs termencoding \
+       tmpfiles.setup
 SHUTDOWN-Linux=        killprocs mount-ro
 SYSINIT-Linux= devfs dmesg sysfs tmpfiles.dev
 

diff --git a/sh/.gitignore b/sh/.gitignore
index d5cb215..c83b730 100644
--- a/sh/.gitignore
+++ b/sh/.gitignore
@@ -8,3 +8,4 @@ init-early.sh
 rc-cgroup.sh
 tmpfiles.sh
 migrate-to-run.sh
+binfmt.sh

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..b636bac
--- /dev/null
+++ b/sh/binfmt.sh.in
@@ -0,0 +1,85 @@
+#!@SHELL@
+# This is a reimplementation of the systemd binfmt.d code to register
+# misc binary formats with the kernel.
+#
+# Copyright (c) 2015 William Hubbs <w.d.hu...@gmail.com>
+# 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
+#
+
+apply_file() {
+       [ $# -lt 1 ] && return 0
+       FILE="$1"
+       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
+
+               echo "${line}" > /proc/sys/fs/binfmt_misc/register
+               rc=$?
+               if [ $rc -ne 0 ]; then
+                       printf "binfmt: invalid entry on line %d of \`%s'\n" \
+                               "$LINENUM" "$FILE" >&2
+                       error=1
+               fi
+       done <$FILE
+       return $rc
+}
+
+[ -e /proc/sys/fs/binfmt_misc/register ] || exit 0
+error=0
+if [ $# -gt 0 ]; then
+       while [ $# -gt 0 ]; do
+               apply_file "$1"
+               shift
+       done
+else
+       # 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
+                       [ -e $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}
+                       [ -e "${f}" ] && real_f=$f
+               done
+               [ -e "${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
+               apply_file "$FILE"
+       done
+fi
+
+exit $error
+
+# vim: set ts=2 sw=2 sts=2 noet ft=sh:

Reply via email to