From e7daaf7fdf80ba63626515ca3e3e3054aaac0417 Mon Sep 17 00:00:00 2001 From: Michael Prokop Date: Thu, 29 Jul 2010 23:28:54 -0400 Subject: init: provide validate_init() wrapper to support absolute symlinks. If /sbin/init is an absolute symlink (e.g. to /bin/systemd) the readlink check doesn't work as $rootmnt is involved. The validate_init() shell function takes care of this fact, as well as when guessing the init binary points to a directory. For example Ubuntu's upstart has its configuration inside /etc/init whereas this is considered a valid run_init_process() binary by the Linux kernel and `test -x' returns true when checking for executables. Therefore be more conservative with providing full backwards compability as well as new added support for absolute symlinks at the same time. Closes: #590744 --- init | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) (limited to 'init') diff --git a/init b/init index 467a562..dee5625 100755 --- a/init +++ b/init @@ -227,24 +227,48 @@ run_scripts /scripts/init-bottom mount -n -o move /sys ${rootmnt}/sys mount -n -o move /proc ${rootmnt}/proc +validate_init() { + checktarget="${1}" + + # Work around absolute symlinks + if [ -d "${rootmnt}" ] && [ -h "${rootmnt}${checktarget}" ]; then + case $(readlink "${rootmnt}${checktarget}") in /*) + checktarget="$(chroot ${rootmnt} readlink ${checktarget})" + ;; + esac + fi + + # Make sure the specified init can be executed + if [ ! -x "${rootmnt}${checktarget}" ]; then + return 1 + fi + + # Upstart uses /etc/init as configuration directory :-/ + if [ -d "${rootmnt}${checktarget}" ]; then + return 1 + fi +} + # Check init bootarg -if [ -n "${init}" ] && [ ! -x "${rootmnt}${init}" ]; then - echo "Target filesystem doesn't have ${init}." - init= +if [ -n "${init}" ]; then + if ! validate_init "$init"; then + echo "Target filesystem doesn't have requested ${init}." + init= + fi fi # Search for valid init if [ -z "${init}" ] ; then - for init in /sbin/init /etc/init /bin/init /bin/sh; do - if [ ! -x "${rootmnt}${init}" ]; then - continue + for inittest in /sbin/init /etc/init /bin/init /bin/sh; do + if validate_init "${inittest}"; then + init="$inittest" + break fi - break done fi # No init on rootmount -if [ ! -x "${rootmnt}${init}" ]; then +if ! validate_init "${init}" ; then panic "No init found. Try passing init= bootarg." fi -- cgit v1.2.3