#!/bin/sh

mknod /dev/console c 5 1
mknod /dev/null c 1 3
mknod /dev/kmsg c 1 11

exec >/dev/kmsg 2>&1 </dev/console

mount -t proc -o nosuid,noexec,nodev proc /proc
mount -t sysfs -o nosuid,noexec,nodev sysfs /sys
mount -t devtmpfs -o mode=755,nosuid devtmpfs /dev
mount -t tmpfs -o mode=755,nosuid,nodev tmpfs /run


rw=0
noresume=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
		;;
	*.*=*)
		echo options ${param%.*} ${param#*.} >> /etc/modprobe.conf
		;;
	esac
done

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

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


echo "initramfs: starting udev"
/lib/systemd/systemd-udevd --daemon --resolve-names=never

udevadm trigger --type=subsystems --action=add
udevadm trigger --type=devices --action=add
udevadm settle


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

if [ -x "/init.local" ]
then
	/init.local
fi

if [ -z "$root" ]
then
	if [ -f "$init" ]
	then
		udevadm control --exit
		udevadm info --cleanup-db
		
		exec "$init" "$@"
	fi

	exec >/dev/console 2>&1 </dev/console < /dev/console
	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 -i
fi

if [ "$root" = "cdrom" ]
then
	echo "initramfs: waiting for cdrom"

	root=

	# wait for cdrom, might happen with usb cdroms
	loop=100
	while [ "$root" = "" ]
	do
		cd /sys/block
		for dev in *
		do
			case $dev in
			sr*)
				root="$root /dev/$dev"
				;;
			esac
		done
		cd /

		sleep 0.1
		test "$loop" -gt 0 || break
		loop=$(($loop - 1))
	done
elif [ "$rootfstype" != "9p" ] && [ "$rootfstype" != "virtiofs" ] && [ ! -e "$root" ]
then
	echo "initramfs: waiting for root device $dev"

	# if root device was not found,
	# start inactive RAID arrays even if there are components missing
	cd /sys/block
	for dev in *
	do
		case $dev in
		md*)
			mdadm --detail /dev/$dev &>/dev/null || mdadm --run /dev/$dev
			;;
		esac
	done
	cd /
	udevadm settle
fi

# go through each root dev candidate and check if it is valid
for dev in $root
do
	# wait for device, might happen with usb devices
	loop=100
	while [ "$rootfstype" != "9p" ] && [ "$rootfstype" != "virtiofs" ] && 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"
	
	echo "initramfs: mounting $dev ($rootfstype filesystem)"
	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 [ -n "$rootunion" ] || [ -f "/root/rootfs.img" ]
			then
				mkdir /run/live
				mount -o move /root /run/live

				LOWERDIR=/run/live

				if [ -f "/run/live/rootfs.img" ]
				then
					mkdir /run/squashfs
					losetup /dev/loop0 /run/live/rootfs.img
				
					mount -t squashfs -o ro /dev/loop0 /run/squashfs

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

					LOWERDIR=/run/squashfs
				fi

				mkdir /run/overlay
				mount -t tmpfs -o mode=755 tmpfs /run/overlay
				
				mkdir /run/overlay/upper
				mkdir /run/overlay/work
				mount -t overlay -o lowerdir=$LOWERDIR,upperdir=/run/overlay/upper,workdir=/run/overlay/work overlay /root

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

			udevadm control --exit
			udevadm info --cleanup-db
			
			mount -o move /proc /root/proc
			mount -o move /sys /root/sys
			mount -o move /dev /root/dev
			mount -o move /run /root/run

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

exec >/dev/console 2>&1 </dev/console < /dev/console
# 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 -i
