#!/bin/busybox sh

echo "Starting up the initramfs, please wait..."

[ -d /run ] || mkdir -m 0755 /run
[ -d /dev ] || mkdir -m 0755 -p /dev/pts
[ -d /root ] || mkdir -m 0700 /root
[ -d /sys ] || mkdir /sys
[ -d /proc ] || mkdir /proc
[ -d /tmp ] || mkdir /tmp
mount -t sysfs -o nodev,noexec,nosuid sysfs /sys 
mount -t proc -o nodev,noexec,nosuid proc /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
if [ -e /etc/udev/udev.conf ]; then
	. /etc/udev/udev.conf
fi
# Mount devtmpfs for /dev, fallback to tmpfs if not supported.
if ! mount -t devtmpfs -o size=10M,mode=0755 devtmpfs /dev; then
	panic "Failed to mount devtmpfs on /dev!"
fi
# Also mount a tmpfs for /run directory.
mount -t tmpfs -o mode=0755,nosuid,nodev tmpfs /run

mkdir -m0755 /run/udev
mkdir -m0755 /run/initramfs

# Set modprobe env
export MODPROBE_OPTIONS="-qb"

# Export relevant variables
export ROOT=
export ROOTDELAY=
export ROOTFLAGS=
export ROOTFSTYPE=
export BOOT=local
export break=
export init=/sbin/init
export quiet=n
export readonly=y
export rootmnt=/root
export debug=
export panic=
export blacklist=
export resume=
export resume_offset=

# Bring in the main config
. /conf/initramfs.conf
for conf in conf/conf.d/*; do
	[ -f ${conf} ] && . ${conf}
done
. /scripts/functions

# Parse command line options
for x in $(cat /proc/cmdline); do
	case $x in
	init=*)
		init=${x#init=}
		;;
	root=*)
		ROOT=${x#root=}
		case $ROOT in
		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=}"
			;;
		esac
		;;
	rootflags=*)
		ROOTFLAGS="-o ${x#rootflags=}"
		;;
	rootfstype=*)
		ROOTFSTYPE="${x#rootfstype=}"
		;;
	rootdelay=*)
		ROOTDELAY="${x#rootdelay=}"
		case ${ROOTDELAY} in
		*[![:digit:].]*)
			ROOTDELAY=
			;;
		esac
		;;
	boot=*)
		BOOT=${x#boot=}
		;;
	resume=*)
		RESUME="${x#resume=}"
		;;
	resume_offset=*)
		resume_offset="${x#resume_offset=}"
		;;
	noresume)
		noresume=y
		;;
	panic=*)
		panic="${x#panic=}"
		case ${panic} in
		*[![:digit:].]*)
			panic=
			;;
		esac
		;;
	quiet)
		quiet=y
		;;
	ro)
		readonly=y
		;;
	rw)
		readonly=n
		;;
	debug)
		debug=y
		quiet=n
		exec >/run/initramfs/initramfs.debug 2>&1
		set -x
		;;
	debug=*)
		debug=y
		quiet=n
		set -x
		;;
	break=*)
		break=${x#break=}
		;;
	break)
		break=premount
		;;
	blacklist=*)
		blacklist=${x#blacklist=}
		;;
	esac
done

if [ -n "${noresume}" ]; then
	export noresume
	unset resume
else
	resume=${RESUME:-}
fi

maybe_break top
log_begin_msg "Running /scripts/init-top"
run_scripts /scripts/init-top
log_end_msg

# Mount devpts to make plymouth happy
[ -d /dev/pts ] || mkdir -m0755 /dev/pts
mount -t devpts devpts /dev/pts

maybe_break modules
log_begin_msg "Loading essential drivers"
load_modules
log_end_msg

maybe_break premount
log_begin_msg "Running /scripts/init-premount"
run_scripts /scripts/init-premount
log_end_msg

maybe_break mount
log_begin_msg "Mounting root file system"
. /scripts/${BOOT}
maybe_break mountroot
mountroot
log_end_msg

maybe_break bottom
log_begin_msg "Running /scripts/init-bottom"
run_scripts /scripts/init-bottom
log_end_msg

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}" ]; then
	if ! validate_init "$init"; then
		echo "Target filesystem doesn't have requested ${init}."
		init=
	fi
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 ! 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
unset MODPROBE_OPTIONS
unset ROOTFLAGS
unset ROOTFSTYPE
unset ROOTDELAY
unset ROOT
unset BOOT
unset blacklist
unset break
unset noresume
unset panic
unset quiet
unset readonly
unset resume
unset resume_offset

# move mounted filesystems to real root.
[ -d ${rootmnt}/dev/pts ] || mkdir -m0755 -p ${rootmnt}/dev/pts
[ -d /dev/pts ] && mount -o move /dev/pts ${rootmnt}/dev/pts
mount -o move /sys ${rootmnt}/sys
mount -o move /proc ${rootmnt}/proc
mount -o move /run ${rootmnt}/run

# Chain to real filesystem
exec switch_root ${rootmnt} ${init} "$@"
panic "Could not execute run-init."
