#!/bin/sh

. /etc/initrd.defaults
. /etc/initrd.scripts

# Clean input/output
exec >${CONSOLE} <${CONSOLE} 2>&1

[ "$$" != '1' ] && bad_msg "This script must run with a PID of 1; exiting." && exit 1

mount -t proc -o noexec,nosuid,nodev proc /proc >/dev/null 2>&1
mount -o remount,rw / >/dev/null 2>&1

# Set up symlinks
/bin/busybox --install -s

echo '0' > /proc/sys/kernel/printk

mkdir -p /newroot
CHROOT=/newroot

mkdir -p /etc/cmdline /etc/modprobe.d
for x in $(cat /proc/cmdline)
do
	case "${x}" in
		real_root=*)
			REAL_ROOT=${x#*=}
		;;
		root=*)
			FAKE_ROOT=${x#*=}
		;;
		real_init=*)
			REAL_INIT=${x#*=}
		;;
		init_opts=*)
			INIT_OPTS=${x#*=}
		;;
		debug)
			DEBUG='yes'
		;;
		quick)
			# enhanced module loading:
			QUICK='yes'
		;;
		slow)
			QUICK=''
		;;
		magic=*)
			# specify magic list of modules to try, comma separated:
			MAGIC="${x#*=}"
			MAGIC="${x/,/ }"
		;;
		real_rootflags=*)
			REAL_ROOTFLAGS=${x#*=}
		;;
		rootfstype=*)
			ROOTFSTYPE=${x#*=}
		;;
	esac
done

if [ -z "${REAL_ROOT}" ] && [  "${FAKE_ROOT}" != "/dev/ram0" ]
then
	REAL_ROOT="${FAKE_ROOT}"
fi

# Mount devfs
mount_devfs

# Mount sysfs
mount_sysfs

# Initialize mdev
good_msg 'Activating mdev'

# Serialize hotplug events
touch /dev/mdev.seq

# Setup hotplugging for firmware loading if hotplug available
test -f /proc/sys/kernel/hotplug && echo /sbin/mdev > /proc/sys/kernel/hotplug

# if the root filesystem type was specified, load this FS module first:
if [ ! -b "${REAL_ROOT}" ] && [ "${ROOTFSTYPE}" != "auto" ]; then
	good_msg "Loading ${ROOTFSTYPE} filesystem..."
	if ! modprobe "$ROOTFSTYPE"; then
		bad_msg "Unable to load root filesystem module $ROOTFSTYPE"
	fi
fi

# If "magic" list of modules was specified, use this and see if this gets us the
# root block device:
if [ "$MAGIC" = "1" ]; then
	good_msg "Loading magic modules..."
	do_modprobe $MAGIC
fi

mdev -s || bad_msg "mdev -s failed"

# This is here to try the "MAGIC" modules and see if they did the trick.
# If so, we can skip the modules scan, below:
if [ "$MAGIC" = "1" ] && determine_root && mount_real_root && sanity_check_root; then
	good_msg "Use of magic modules allowed us to find the root block device early..."
fi

if [ "${MOUNTED_ROOT_FS}" != '1' ] && [ "${DETECT}" != '0' ]
then
	good_msg "Starting modules scanning..."
	for modules in nvme sata scsi filesystems usb usb-storage usb-input
	do
		modules_scan ${modules}
		mdev -s || bad_msg "mdev -s failed"
		# The "quick" boot option tells the linuxrc to try to short-circuit module loading if we
		# appear successful:
		[ -n "$QUICK" ] && determine_root && mount_real_root && sanity_check_root && break
	done
fi

[ -n "$DEBUG" ] && good_msg 'Starting debug shell as requested by "debug" option.' && run_shell

while [ "${MOUNTED_ROOT_FS}" != "1" ]; do
	determine_root && mount_real_root && sanity_check_root && break
	# If we fail, prompt user for root block device.
	run_shell
done

echo '6' > /proc/sys/kernel/printk

for dirp in proc sys run; do
	[ ! -d "${CHROOT}/${dirp}" ] && mkdir -p "${CHROOT}/${dirp}" 2>/dev/null
done

for fs in /dev /sys /proc
do
	if mountpoint -q $fs; then
		if ! mount --move $fs "${CHROOT}"$fs
		then
			umount $fs || bad_msg "ERROR: Failed to move and unmount the ramdisk $fs!"
		fi
	fi
done

sanity_check_root postmount || run_shell

cd / && exec /sbin/switch_root -c "/dev/console" "${CHROOT}" "${REAL_INIT:-/sbin/init}" "${INIT_OPTS}"

bad_msg "Something prevented us from switching into root filesystem."
run_shell