#!/bin/sh

fail()
{
echo -e '\033[70G[ \033[1;3'${1:-1mFailed}'\033[0;39m ]'
}

quit()
{
[ -d /mnt$4/etc ] || return
[ -n "$4" ] || mount /mnt -o remount,ro
mount --move /run /mnt/${1:-run}
cat>/run/init<<EOT
$2
x=/sbin/switch_root
[ -x \$x ] && exec \$x mnt $3 /sbin/init
EOT
fail 2mDone
exit
}

arg()
{
grep -q $1 /proc/cmdline
}

got()
{
arg $1= && root="$(sed "s/.*$1=\([^ ]*\).*/\1/" </proc/cmdline)"
}

msg()
{
echo "Switching / to $1..."
}

use()
{
got $1 && msg "$1 $root"
}

mnt()
{
r=${root#/dev/}
r=/dev/${r%%/*}
d=${root#*$r}
mount $r $1 && return
w=$(cat /sys/module/usb_storage/parameters/delay_use)
w=$((1+${w:-2}))
echo -n "Sleep $w seconds..."
sleep $w
mount $r $1
}

mod()
{
modprobe $1 2>/dev/null || insmod $(find /lib/modules|sed "/$1.ko/!dq") 
}

try()
{
if [ ! -d /mnt/etc ] && got cryptoroot
then	mod dm-mod
	mod dm-crypt
	mod aes-i586
	d=${root#/dev/}
	l=crypto-$d
	if cryptsetup isLuks $root 2>/dev/null; then
		cryptsetup luksOpen $root $l
	else
		read -st 60 -p "Pass phrase : " p
		k=$(echo $p|hashalot -x -n 32 sha512)
		echo 0 $(cat $(find /sys/block|grep /$d/size))\
		crypt aes-plain $k 0 $root 0|dmsetup create $l
	fi
	mount /dev/mapper/$l /mnt
fi
got subroot && return
got loopfs && return
if [ -d /mnt/etc ]
then	for i in $@; do cp -a $i /mnt$(dirname $i); done
	quit
fi
fail
}

lvm()
{
use lvmroot || return
mod dm-mod
vgscan --ignorelockingfailure
vgchange -ay --ignorelockingfailure
mount /dev/mapper/$root /mnt
try /dev/mapper $1
}

ldraid()
{
while read l
do case "$l" in
*raid10*)	mod raid10;;
*raid0*)	mod raid0;;
*raid1*)	mod raid1;;
*raid*)		mod raid456;;
*mirror*)	mod dm-mirror
esac
done
}

if [ "$1" != "log" ]
then	mount -t proc proc /proc
	mount -t sysfs sys /sys
	mount -t tmpfs tmpfs /run
	x=/sbin/init; echo "[ -x $x ] && exec $x" >/run/init
	$0 log 2>&1 | tee /run/boot.log
	umount /proc
	umount /sys
	. /run/init
	sh
fi
ln -s $(sed '/name/!ds/.*:[^a-z]*//' /proc/sys/dev/cdrom/info) /dev/cdrom
if use dmraid
then	dmraid -s|sed '/^type/!ds/.*: *//'|ldraid
	[ ${root:0:4} = /dev ] ||
	root=/dev/mapper/$(dmraid -s|sed '/^name/!ds/.*: *//')p${root#p}
	dmraid -ay
fi
if use softraid
then	mdadm -E -s -c partitions>/etc/mdadm.conf
	grep -qs " $root " /etc/mdadm.conf ||
	root=$(awk '/dev.md/{print $2;exit}'</etc/mdadm.conf)
	grep level=raid /etc/mdadm.conf|ldraid
	for i in 1 2 3 4 5 6 7 8 9
	do	sleep $i
		mdadm -A -s
		grep -qs ': act' /proc/mdstat && break
	done
	lvm /etc/mdadm.conf
fi
lvm
if got mount
then	dev=$root
	x=$(blkid|grep $dev|sed 's/:.*//;q')
	root=${x:-$dev}
	[ "$dev" = "$root" ] || dev="$root ($dev)"
	echo "Mount $dev..."
	mnt /mnt
	arg posixovl && echo "And posixovl..." && mount.posixovl /mnt
fi
got loopfs && echo "Into file $root..." &&
	losetup /dev/loop0 /mnt/$root && mount /dev/loop0 /mnt
got bindfs && echo "Bind ${root/,/ to }..." &&
	mount --bind /mnt/${root%,*} /mnt/${root/,//}
arg cryptoroot= && try
if use subroot
then	cp $(LD_TRACE_LOADED_OBJECTS=1 /lib/ld*.so /usr/sbin/chroot | sed\
		's|.*=> \(/lib/l[^ ]*\).*|\1|;/^\//!d') /usr/sbin/chroot /run
	r=$root/run
	quit $r "export LD_LIBRARY_PATH=$r:/lib"\
		"$root$(ls /run/ld-*so) $r/chroot $root" "/$root"
fi
quit
msg tmpfs
root=100
got tmpram
r=$root
root=90%
got rootfssize
[ $(busybox free|busybox awk '/Mem:/{print int(($4*100)/$3)}') -ge $r ] &&
mount -t tmpfs -o size=$root tmpfs /mnt &&
for i in $(ls -ar /)
do	case "$i" in
	.*|cdrom)	;;
	mnt|proc|sys)	mkdir /mnt/$i;;
	usr|var|rootfs*) mv /$i /mnt;;
	*)	cp -a /$i /mnt 2>/dev/null && continue
		fail
		umount /mnt
		exit
	esac
done || fail 3mSkipped
quit
mod squashfs 2>/dev/null || exit
msg aufs
br=/mnt/.rw
mkdir $br
got rwdev && mnt $br && br=$br$d
o=
p=
c=/mnt/.cdrom
if [ -z "$(ls /mnt/rootfs* 2>/dev/null)" ]
then	root=cdrom/fs
	got rodev
	mkdir -p $c /mnt$c /mnt/.rw$c
	mnt $c
	o="-o 124"
	p=/.cdrom/boot
	c=$c$d
fi
l=0
r=
got isofs || for i in /mnt$p/rootfs?*.gz
do	fs=${i#*root}
	r=$r:/mnt/.$fs
	mkdir -p /mnt/.rw/mnt/.$fs /mnt/.$fs
	losetup $o /dev/loop$l $i
	mount -o ro -t squashfs /dev/loop$((l++)) /mnt/.$fs
done
mod aufs
mount -t aufs -o br=$br${r:-:$c} none /mnt
quit
