#!/bin/sh

PATH=/sbin:/bin:/usr/bin:/usr/sbin

LOG=/linuxrc.log

KERNEL_VERSION=$(uname -r)

message_disable_initrd()
{
	echo "Try to run coLinux without initrd.  Comment out initrd from configuration."
	echo "Please install modules manualy."
	sleep 1
	echo -e "\nPress <ENTER> to continue"
	read junk
}

install_modules()
{

	# rootfs mounted right?
	if [ ! -d /mnt/linux/etc ]; then
		return
	fi

	# modules exist on rootfs?
	if [ -d /mnt/linux/lib/modules/$KERNEL_VERSION ]; then
		echo "Modules already installed." | tee -a $LOG
		return
	fi

	echo "Installing modules for coLinux $KERNEL_VERSION" | tee -a $LOG

	echo "remount rootfs rw" >> $LOG
	mount -o remount,rw $ROOTDEV /mnt/linux 2>> $LOG

	# search device with path to lib/modules
	while read device mountpoint type opts dump
	do
		case "$device" in
		/dev/*)
			case "$mountpoint" in
			/lib)
				echo "mount lib" >> $LOG
				device="$(echo $device | sed -r -e 's|(/dev/.+)/([0-9]+)|\1\2|')"
				mount $device /mnt/linux$mountpoint -t $type 2>&1 >> $LOG
				lib_dev=$device
			;;
			/lib/modules)
				echo "mount modules" >> $LOG
				device="$(echo $device | sed -r -e 's|(/dev/.+)/([0-9]+)|\1\2|')"
				mount $device /mnt/linux$mountpoint -t $type 2>&1 >> $LOG
				modules_dev=$device
			;;
			esac
		;;
		esac
	done < /mnt/linux/etc/fstab

	if [ -d /mnt/linux/lib/modules/$KERNEL_VERSION ]; then
		echo "Skipping." | tee -a $LOG
	else
		MODFILE=vmlinux-modules.tar.gz
		if [ ! -f /lib/modules/$MODFILE ]; then
			echo "Mounting cofs for vmlinux-modules.tar.gz" | tee -a $LOG
			# TODO: get cofs index number from proc fs
			if mount -o ro -t cofs 31 /lib/modules
			then
				if [ -f /lib/modules/modules-$KERNEL_VERSION.tgz ]; then
					MODFILE=modules-$KERNEL_VERSION.tgz
				fi
			else
				echo "failed" | tee -a $LOG
			fi
		fi

		if [ -f /lib/modules/$MODFILE ]; then
			echo "untar $MODFILE" >> $LOG
			if tar zxf /lib/modules/$MODFILE -C /mnt/linux 2>&1 >> $LOG
			then
				if [ -f /mnt/linux/lib/modules/$KERNEL_VERSION/modules.dep ]; then
					chown -R 0:0 /mnt/linux/lib/modules/$KERNEL_VERSION 2>> $LOG
					touch /mnt/linux/lib/modules/$KERNEL_VERSION/modules.dep
					echo "done" | tee -a $LOG
				else
					echo "initrd: Missing modules.dep in $MODFILE." | tee -a $LOG
				fi
			fi
			sync; sleep 1
		else
			echo -e "\ninitrd: $MODFILE not found in cofs31" | tee -a $LOG
			message_disable_initrd
		fi

		umount /lib/modules 2>/dev/null
	fi

	# Create console for boot with udev
	if [ ! -c /mnt/linux/dev/console ]; then
		mknod /mnt/linux/dev/console c 5 1
	fi

	# Need umount lib/modules?
	if [ -n "$modules_dev" ]; then
		echo "umount modules" >> $LOG
		umount $modules_dev 2>&1 >> $LOG
		sync; sleep 1
	fi

	if [ -n "$lib_dev" ]; then
		echo "umount lib" >> $LOG
		umount $lib_dev 2>&1 >> $LOG
		sync; sleep 1
	fi
}

# Re-mount in rw mode (in case ro was passed on boot)
echo "(Re)mount / read-write" >> $LOG
mount -o remount,rw / 2>> $LOG

# Mount filesystems in /etc/fstab.
echo  "Mount proc: " >> $LOG
mount -t proc /proc /proc 2>&1 | tee -a $LOG

# Read boot command line (use cat, shell read function may fail)
CMDLINE="$(cat /proc/cmdline)"

# Display /etc/issue file.
echo  "Displaying /etc/issue file" >> $LOG
if [ -s /etc/issue ]; then
	cat /etc/issue
fi

sleep 1

echo -n "Determining /" 
echo "Determining /" >> $LOG
ROOTDEV=/dev/root
for barg in ${CMDLINE}; do
    ROOTDEV=`IFS='='; set ${barg}; [ $1 = root ] && echo $2`
    if [ -n "${ROOTDEV}" ]; then 
	# Transform /dev/cobd/0 into /dev/cobd0 for udev
	ROOTDEV="$(echo $ROOTDEV | sed -r -e 's|(/dev/.+)/([0-9]+)|\1\2|')"
	echo ", Found."
	break
    fi
done
echo " ($ROOTDEV) " >> $LOG

echo "Mounting /" | tee -a $LOG
if mount -o ro $ROOTDEV /mnt/linux
then
	install_modules

	echo "Closing /" | tee -a $LOG
	if ! umount -f /mnt/linux 2>&1 >> $LOG
	then
		echo "Failed. (trying again)"
		sync ; sleep 1
		if ! umount -f /mnt/linux
		then
			echo -e "\ninitrd: umount failed on rootfs"
			message_disable_initrd
		fi
		sync
	fi
fi

sync

# Freeing proc that was auto-mounted earlier
umount /proc 2>&1 >> $LOG
sync
