diff options
Diffstat (limited to 'init')
-rwxr-xr-x | init | 134 |
1 files changed, 105 insertions, 29 deletions
@@ -8,8 +8,8 @@ echo "Loading, please wait..." [ -d /proc ] || mkdir /proc [ -d /tmp ] || mkdir /tmp mkdir -p /var/lock -mount -t sysfs -o nodev,noexec,nosuid none /sys -mount -t proc -o nodev,noexec,nosuid none /proc +mount -t sysfs -o nodev,noexec,nosuid none /sys +mount -t proc -o nodev,noexec,nosuid none /proc # Note that this only becomes /dev on the real filesystem if udev's scripts # are used; which they will be, but it's worth pointing out @@ -17,9 +17,14 @@ tmpfs_size="10M" if [ -e /etc/udev/udev.conf ]; then . /etc/udev/udev.conf fi -mount -t tmpfs -o size=$tmpfs_size,mode=0755 udev /dev -[ -e /dev/console ] || mknod -m 0600 /dev/console c 5 1 -[ -e /dev/null ] || mknod /dev/null c 1 3 +if ! mount -t devtmpfs -o mode=0755 none /dev; then + echo "W: devtmpfs not available, falling back to tmpfs for /dev" + mount -t tmpfs -o size=$tmpfs_size,mode=0755 udev /dev + [ -e /dev/console ] || mknod -m 0600 /dev/console c 5 1 + [ -e /dev/null ] || mknod /dev/null c 1 3 +fi +mkdir /dev/pts +mount -t devpts -o noexec,nosuid,gid=5,mode=0620 none /dev/pts || true > /dev/.initramfs-tools mkdir /dev/.initramfs @@ -35,6 +40,10 @@ export ROOT= export ROOTDELAY= export ROOTFLAGS= export ROOTFSTYPE= +export IP= +export BOOT= +export BOOTIF= +export UBIMTD= export break= export init=/sbin/init export quiet=n @@ -43,6 +52,7 @@ export rootmnt=/root export debug= export panic= export blacklist= +export resume= export resume_offset= # Bring in the main config @@ -62,7 +72,30 @@ for x in $(cat /proc/cmdline); do ROOT=${x#root=} case $ROOT in LABEL=*) - ROOT="/dev/disk/by-label/${ROOT#LABEL=}" + ROOT="${ROOT#LABEL=}" + + # support any / in LABEL= path (escape to \x2f) + case "${ROOT}" in + */*) + if command -v sed >/dev/null 2>&1; then + ROOT="$(echo ${ROOT} | sed 's,/,\\x2f,g')" + else + if [ "${ROOT}" != "${ROOT#/}" ]; then + ROOT="\x2f${ROOT#/}" + fi + if [ "${ROOT}" != "${ROOT%/}" ]; then + ROOT="${ROOT%/}\x2f" + fi + IFS='/' + newroot= + for s in $ROOT; do + newroot="${newroot:+${newroot}\\x2f}${s}" + done + unset IFS + ROOT="${newroot}" + fi + esac + ROOT="/dev/disk/by-label/${ROOT}" ;; UUID=*) ROOT="/dev/disk/by-uuid/${ROOT#UUID=}" @@ -90,11 +123,14 @@ for x in $(cat /proc/cmdline); do NFSROOT="${x#nfsroot=}" ;; ip=*) - IPOPTS="${x#ip=}" + IP="${x#ip=}" ;; boot=*) BOOT=${x#boot=} ;; + ubi.mtd=*) + UBIMTD=${x#ubi.mtd=} + ;; resume=*) RESUME="${x#resume=}" ;; @@ -141,25 +177,33 @@ for x in $(cat /proc/cmdline); do blacklist=*) blacklist=${x#blacklist=} ;; + netconsole=*) + netconsole=${x#netconsole=} + ;; + BOOTIF=*) + BOOTIF=${x#BOOTIF=} + ;; esac done -if [ -z "${noresume}" ]; then - export resume=${RESUME} -else +if [ -n "${noresume}" ]; then export noresume + unset resume +else + resume=${RESUME:-} fi -depmod -a +[ -n "${netconsole}" ] && modprobe netconsole netconsole="${netconsole}" + maybe_break top # Don't do log messages here to avoid confusing usplash run_scripts /scripts/init-top maybe_break modules -log_begin_msg "Loading essential drivers" +[ "$quiet" != "y" ] && log_begin_msg "Loading essential drivers" load_modules -log_end_msg +[ "$quiet" != "y" ] && log_end_msg maybe_break premount [ "$quiet" != "y" ] && log_begin_msg "Running /scripts/init-premount" @@ -183,27 +227,56 @@ 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 - fi - break - done -fi +# Common case: /sbin/init is present +if [ ! -x "${rootmnt}/sbin/init" ]; then + # ... if it's not available search for valid init + if [ -z "${init}" ] ; then + for inittest in /sbin/init /etc/init /bin/init /bin/sh; do + if validate_init "${inittest}"; then + init="$inittest" + break + fi + done + fi -# No init on rootmount -if [ ! -x "${rootmnt}${init}" ]; then - panic "No init found. Try passing init= bootarg." + # No init on rootmount + if ! validate_init "${init}" ; then + panic "No init found. Try passing init= bootarg." + fi fi +maybe_break init + # don't leak too much of env - some init(8) don't clear it # (keep init, rootmnt) unset debug @@ -213,6 +286,10 @@ unset ROOTFLAGS unset ROOTFSTYPE unset ROOTDELAY unset ROOT +unset IP +unset BOOT +unset BOOTIF +unset UBIMTD unset blacklist unset break unset noresume @@ -223,6 +300,5 @@ unset resume unset resume_offset # Chain to real filesystem -maybe_break init exec run-init ${rootmnt} ${init} "$@" <${rootmnt}/dev/console >${rootmnt}/dev/console panic "Could not execute run-init." |