#!/bin/sh

mount -t tmpfs tmpfs /dev
mount -t proc proc /proc
mount -t sysfs sysfs /sys

udevd --daemon

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

udevtrigger
udevsettle

# ensure SCSI scans have completed
modprobe scsi_wait_scan
udevsettle

raidautorun

# wait for RAID and DM events
udevsettle

# trigger md0 uevent after activating RAID devices
# to get persistent device names (md0 always exists)
echo -n add > /sys/block/md0/uevent
udevsettle


rw=0
noresume=0
nodmraid=0
init="/sbin/init"
dev="$1"

read cmdline < /proc/cmdline

for param in $cmdline ; do
	case "$param" in
	root=*|rootfstype=*|rootflags=*|init=*|rootunion=*|resume=*)
		eval "$param"
		;;
	ro)
		rw=0
		;;
	rw)
		rw=1
		;;
	noresume)
		noresume=1
		;;
	nodmraid)
		nodmraid=1
		;;
	esac
done

if [ ! -z "$rootflags" ]
then
	rootflags="$rootflags,"
fi

if [ "$rw" = 1 ]
then
	rootflags="$rootflags"rw
else
	rootflags="$rootflags"ro
fi

if [ "$nodmraid" = 0 ]
then
	# Find out if there are any dmraid supported software raid controllers and setups available
	# and enable device-mapper if some are found
	dmraid -r | (
		while read dev ; do
			case "$dev" in 
			/dev/*)
				modprobe dm-mod
				dmraid -ay
				break
				;;
			esac
		done
	)
fi

# Try to resume from suspend-to-disk
if [ -n "$resume" ] && [ -e "$resume" ] && [ "$noresume" = 0 ] && [ -w /sys/power/resume ]
then
	cat /sys$(udevinfo -q path -n $resume)/dev > /sys/power/resume
fi

if [ -z "$root" ]
then
	if [ -f "$init" ]
	then
		minips h -C udevd | (
			while read pid info
			do
				kill $pid
			done
		)
		
		exec "$init" "$@"
	fi
	
	echo "No root filesystem specified"
	echo "Please append a correct \"root=\" boot option"
	echo "Dropping you to a limited shell. To reboot press CTRL-ALT-Delete..."
	exec /bin/sh
fi

if [ "$root" = "cdrom" ]
then
	root=

	# wait for cdrom, might happen with usb cdroms
	loop=50
	while [ "$root" = "" ]
	do
		cd /sys/block
		for dev in *
		do
			case $dev in
			hd*)
				if [ "$(cat /proc/ide/$dev/media)" = "cdrom" ]
				then
					root="$root /dev/$dev"
				fi
				;;
			sr*)
				root="$root /dev/$dev"
				;;
			esac
		done
		cd /

		sleep 0.1
		test "$loop" -gt 0 || break
		loop=$(($loop - 1))
	done
fi

if [ "$rootfstype" = "nfs" ]
then
	ipconfig all
fi

# go through each root dev candidate and check if it is valid
for dev in $root
do
	if [ "$rootfstype" = "nfs" ]
	then
		mountcommand="nfsmount -o $rootflags $root /root"
	else
		# wait for device, might happen with usb devices
		loop=50
		while test ! -e "$dev"
		do
			sleep 0.1
			test "$loop" -gt 0 || continue 2
			loop=$(($loop - 1))
		done

		if [ -z "$rootfstype" ]
		then
			eval $(fstype < $dev 2>/dev/null)
			rootfstype="$FSTYPE"
			if [ "$rootfstype" = "unknown" ]
			then
				rootfstype=
				continue
			fi
		fi

		mountcommand="mount -t $rootfstype -o $rootflags $dev /root"
	fi
	
	if $mountcommand
	then
		# wait for filesystem
		loop=20
		while test ! -f "/root$init" && [ ! -f "/root/rootfs.img" ]
		do
			sleep 0.1
			test "$loop" -gt 0 || break
			loop=$(($loop - 1))
		done

		# is this a valid device?
		if [ -f "/root$init" ] || [ -f "/root/rootfs.img" ]
		then
			if [ $rw -eq 1 ]
			then
				echo "Mounted $dev as root ($rootfstype filesystem)." >/dev/console
			else
				echo "Mounted $dev as root ($rootfstype filesystem) readonly." >/dev/console
			fi

			if [ -n "$rootunion" ] || [ -f "/root/rootfs.img" ]
			then
				mkdir /.tmpfs
				mount -t tmpfs -o size=80% tmpfs /.tmpfs
				
				mkdir /.tmpfs/.ro
				mount -o move /root /.tmpfs/.ro
				
				if [ -f "/.tmpfs/.ro/rootfs.img" ]
				then
					mkdir /.tmpfs/.sqfs
					losetup /dev/loop0 /.tmpfs/.ro/rootfs.img
				
					mount -t squashfs -o ro /dev/loop0 /.tmpfs/.sqfs

					# wait for filesystem
					loop=20
					while test ! -f "/.tmpfs/.sqfs$init"
					do
						sleep 0.1
						test "$loop" -gt 0 || break
						loop=$(($loop - 1))
					done
					
					mkdir -p /.tmpfs/.overlay
					
					mount -t aufs -o dirs=/.tmpfs/.overlay=rw:/.tmpfs/.sqfs=ro aufs /root

					mkdir -p /root/media/cdrom
					mount -o move /.tmpfs/.ro /root/media/cdrom
				else
					mkdir -p /.tmpfs/.overlay
					
					mount -t aufs -o dirs=/.tmpfs/.overlay=rw:/.tmpfs/.ro=ro aufs /root
				fi

				# wait for filesystem
				loop=20
				while test ! -f "/root$init"
				do
					sleep 0.1
					test "$loop" -gt 0 || break
					loop=$(($loop - 1))
				done

				mkdir /root/.tmpfs
				mount -o move /.tmpfs /root/.tmpfs
			fi

			minips h -C udevd | (
				while read pid info
				do
					kill $pid
				done
			)
			
			[ -e /root/sys ] && mount -o move /sys /root/sys || umount /sys
			[ -e /root/proc ] && mount -o move /proc /root/proc || umount /proc
			[ -e /root/dev ] && mount -o move /dev /root/dev || umount /dev

			exec run-init /root "$init" "$@"
		else
			# if we get here the device could be mounted but is not valid
			umount /root
		fi
	fi
done

# If we get here we were not able to find a valid root device - time to abort
echo "Unable to find a valid root device/partition"
echo "Please append correct \"root=\" and \"rootfstype=\" boot options"
echo "Dropping you to a limited shell. To reboot press CTRL-ALT-Delete..."
exec /bin/sh
