aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--init.d/Makefile2
-rw-r--r--init.d/binfmt.in20
-rw-r--r--init.d/procfs.in13
-rw-r--r--runlevels/Makefile3
-rw-r--r--sh/.gitignore1
-rw-r--r--sh/Makefile6
-rw-r--r--sh/binfmt.sh.in85
7 files changed, 113 insertions, 17 deletions
diff --git a/init.d/Makefile b/init.d/Makefile
index 85925b15..0bd3651b 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 00000000..651b1315
--- /dev/null
+++ b/init.d/binfmt.in
@@ -0,0 +1,20 @@
+#!@SBINDIR@/openrc-run
+# Copyright 2015 William Hubbs <w.d.hubbs@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 dfe58cb6..167a1aa3 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 25e3e1ab..682d6e15 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 d5cb215a..c83b730b 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 c1953f31..8f742dc8 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 00000000..b636bac7
--- /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.hubbs@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: