summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Prokop <mika@debian.org>2010-07-29 23:28:54 -0400
committerMichael Prokop <mika@debian.org>2010-08-06 23:02:05 -0400
commite7daaf7fdf80ba63626515ca3e3e3054aaac0417 (patch)
tree225954a4bff3531fe5fd82b1292024ca801afa4d
parenta4e1a9ea7321799da65a11bb96413d66b7cb07eb (diff)
downloadinitramfs-tools-e7daaf7fdf80ba63626515ca3e3e3054aaac0417.tar.gz
initramfs-tools-e7daaf7fdf80ba63626515ca3e3e3054aaac0417.zip
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
-rwxr-xr-xinit40
1 files changed, 32 insertions, 8 deletions
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