#!/bin/busybox sh

/bin/busybox --install -s /bin

NEWROOT=/newroot
init=/sbin/init
root=
rootdelay=10
rootfstype=auto
ro="ro"
rootflags=
device=

# print the block device for a /dev path, UUID= or LABEL=
find_device() {
	case "$1" in
		UUID=*|LABEL=*) findfs "$1" 2>/dev/null ;;
		*             ) echo "$1" ;;
	esac
}

# like find_device, but retry for up to $rootdelay seconds
wait_device() {
	dev=$(find_device "$1")
	i=0
	while [ ! -b "$dev" ] && [ "$i" -lt "${rootdelay:-0}" ]; do
		echo ">> waiting for $1..." >&2
		sleep 1
		i=$((i+1))
		dev=$(find_device "$1")
	done
	echo "$dev"
}

# source hook scripts added by mkinitrd, in the order of /hooks/order:
#   pre  - before the root filesystem is mounted, a hook may mount it itself
#   post - after it is mounted, before /proc, /sys, /dev and /run are moved
#          into it, in reverse order
run_hooks() {
	for hook in $($2 /hooks/order 2>/dev/null); do
		[ -f "/hooks/$hook.$1" ] && . "/hooks/$hook.$1"
	done
}

mkdir -p $NEWROOT
mount -t proc     proc  /proc
mount -t sysfs    sysfs /sys
mount -t tmpfs    run   /run
mount -t devtmpfs dev   /dev

# set by ROOTFSTYPE in mkinitrd.conf, rootfstype= on the cmdline overrides it
[ -f /etc/rootfstype ] && read -r rootfstype < /etc/rootfstype

read -r cmdline < /proc/cmdline

for param in $cmdline; do
	case $param in
		init=*      ) init=${param#init=}             ;;
		root=*      ) root=${param#root=}             ;;
		rootdelay=* ) rootdelay=${param#rootdelay=}   ;;
		rootfstype=*) rootfstype=${param#rootfstype=} ;;
		rootflags=* ) rootflags=${param#rootflags=}   ;;
		ro          ) ro="ro"                         ;;
		rw          ) ro="rw"                         ;;
		shell       ) shell=1                         ;;
	esac
done

run_hooks pre cat

[ "$shell" ] && sh

[ "$rootflags" ] && rootflags="$rootflags,"
rootflags="$rootflags$ro"

if ! mountpoint -q $NEWROOT; then
	[ "$root" ] || { echo "!! no root device specified"; exec sh; }

	device=$(wait_device "$root")

	if [ ! -b "$device" ]; then
		echo "!! device '$root' not found"
		exec sh
	fi

	if ! mount -n -t "$rootfstype" -o "$rootflags" "$device" $NEWROOT; then
		echo "!! failed to mount device '$device'"
		exec sh
	fi
fi

[ "$shell" ] && sh

run_hooks post tac

mount --move /sys $NEWROOT/sys
mount --move /proc $NEWROOT/proc
mount --move /dev $NEWROOT/dev
mount --move /run $NEWROOT/run

# switch to newroot
exec switch_root $NEWROOT "$init" "$@"

echo ">> this is the end of initramfs"
echo ">> nothing further, here's the shell"
busybox sh
