#!/bin/bash

#Defaults
init="/sbin/init"
# type of boot medium (ro=read-only (default), rw=read-write)
medium="ro"


###############################################################################
#  0. Set path
#  ~~~~~~~~~~~
###############################################################################
export PATH="/bin:/sbin"

###############################################################################
#  1. Mount kernel file systems
#  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
#  Straight forward - no special comments
#
###############################################################################
[[ -d "/proc/" ]] || mkdir /proc
mount -n proc /proc -t proc
[[ -d "/sys/" ]] || mkdir /sys
mount -n sys /sys -t sysfs


###############################################################################
#  2. Install BusyBox
#  ~~~~~~~~~~~~~~~~~~
###############################################################################
#Create all the symlinks to /bin/busybox
echo "-------------> Create all the symlinks to /bin/busybox"
busybox --install -s

###############################################################################
#  3. Create device nodes
#  ~~~~~~~~~~~~~~~~~~~~~~
###############################################################################
mknod /dev/null c 1 3
mknod /dev/tty c 5 0
mkdir /dev/pts
mkdir /dev/shm
ln -snf /proc/self/fd /dev/fd
ln -snf /proc/self/fd/0 /dev/stdin
ln -snf /proc/self/fd/1 /dev/stdout
ln -snf /proc/self/fd/2 /dev/stderr
ln -snf /proc/kcore /dev/core

###############################################################################
#  4. Set default CONSOLE variable
#  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
###############################################################################
# Exporting CONSOLE. init redirects the standard output and standard error
# of its children to $CONSOLE.
echo "-------------> Setting console"
export CONSOLE='/dev/console'


###############################################################################
#  5. Start udev
#  ~~~~~~~~~~~~~
###############################################################################
echo "-------------> Creating device nodes with udev"
# disable hotplug helper, udevd listens to netlink
if [ `cat /proc/sys/kernel/hotplug` ] ; then
	echo "" > /proc/sys/kernel/hotplug
fi
# Wait until kernel finish to initialize
# unix sockets (Protocol family 1), that appear to be requierment for glibc
# Skipping the wait may lead to messages like
# 	request_module: runaway loop modprobe net-pf-1
while ! dmesg |grep -q 'NET: Registered protocol family 1$'; do
	usleep 100000
done

# start udev daemon
echo "-------------> Starting udevd"
/sbin/udevd --daemon

# start coldplugging
# unlikely, but we may be faster than the first event
mkdir -p /dev/.udev/queue

# configure all devices - let the rush begin... :)
/sbin/udevadm trigger

# We have to wait until settle-down (ETH0 !!)
/sbin/udevadm settle --timeout=5

###############################################################################
#  6. Process command line options
#  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
###############################################################################
echo "-------------> Processing command line"
for i in $(cat /proc/cmdline); do
	case $i in
		root\=*)
			PART=${i#root=}
			;;
		init\=*)
			init=${i#init=}
			;;
		medium\=*)	# spezial ;-)
			medium=${i#medium=}
			;;
	esac
done

###############################################################################
#  7. Prepare Crypto-Device
#  ~~~~~~~~~~~~~~~~~~~~~~~~
###############################################################################
modprobe dm_crypt
/bin/sleep 2

# Check, if we have a crypted partition
ERG=`cryptsetup isLuks $PART >/dev/null`
ERG=$?

if [ $ERG -eq 0 ]
then
	echo "Opening crypto-partition..."
	sleep 2
	MOUNT_DEV="/dev/mapper/root"

	## activate Crypto-Device
	cryptsetup luksOpen $PART root
else
	echo "Opening normal partition..."
	sleep 2
	MOUNT_DEV=$PART
fi

###############################################################################
#  8. Stop udev subsystem
#  ~~~~~~~~~~~~~~~~~~~~~~
###############################################################################
echo "-------------> Stopping udev"
sleep 1
udevadm control --stop-exec-queue
killall udevd

###############################################################################
#  9. Mount the root device
#  ~~~~~~~~~~~~~~~~~~~~~~~~
###############################################################################
# BB-Mount wants to have a mtab ???
echo "-------------> Setting mtab"
ln -s /proc/mounts /etc/mtab

if [ "$medium" = "rw" ]
then
	# Set newroot to wr-medium
	echo "-------------> Booting from a rw medium"
	echo "-------------> Mounting $PART on /newroot:"
	mount -n $MOUNT_DEV /newroot
else
	# Use aufs for newroot
	echo "-------------> Booting from a ro medium"
	mkdir /ramroot
	mkdir /roroot
	mount -t tmpfs tmpfs /ramroot
	mount -n -o ro $MOUNT_DEV /roroot
	mount -n -t aufs -o br=/ramroot:/roroot none /newroot
fi

echo "-------------> Create early device nodes on /newroot"
mkdir -p /newroot/dev
mount -n -t tmpfs udev /newroot/dev -o mode=755
mknod /newroot/dev/null c 1 3
mknod /newroot/dev/console c 5 1


#Check if $init exists and is executable
echo "-------------> Switching root"
if [[ -x "/newroot/${init}" ]] ; then
	#Unmount all other mounts so that the ram used by
	#the initramfs can be cleared after switch_root
	umount -l /sys /proc

	#Switch to the new root and execute init
	exec switch_root /newroot "${init}" <$CONSOLE >$CONSOLE 2>&1
fi

#This will only be run if the exec above failed
echo "-------------> Failed to switch_root, dropping to a shell"
exec bash
