#!/sbin/runscript

# script that will mount image with modules

depend() {
	need dev
	before checkfs fsck hwdrivers modules hwclock
	keyword novserver
}

# read kernel options
init_KOPT() {
	eval set -- $(cat /proc/cmdline 2>/dev/null)
	# in case syslinux does not set BOOT_IMAGE
	KOPT_BOOT_IMAGE="${1}"
	for opt; do
	        case "$opt" in
			alpine_dev=*|modloop=*|BOOT_IMAGE=*)
				eval "KOPT_${opt%%=*}='${opt#*=}'" ;;
        	esac
	done
}

resolve_dev() {
	case "$1" in
	UUID=*|LABEL=*) findfs "$1";;
	*) readlink -f "$1";;
	esac
}

find_mnt() {
	local search_dev="$1" fstab="$2"
	local dev mnt fs mntopts chk
	case "$search_dev" in
		UUID=*|LABEL=*|/dev/*);;
		*) search_dev=/dev/$search_dev;;
	esac
	local search_real_dev=$(resolve_dev $search_dev)
	while read dev mnt fs mntopts chk; do
		local real_dev=$(resolve_dev $dev)
		local i j
		for i in "$search_dev" "$search_real_dev"; do
			[ -z "$i" ] && continue
			for j in "$dev" "$real_dev"; do
				[ -z "$j" ] && continue
				if [ "$i" = "$j" ]; then
					echo "$mnt"
					return
				fi
			done
		done
	done < $fstab 2>/dev/null
}

# initialies: alpine_dev, alpine_mnt, alpine_fs, alpine_mounted
find_media() {
	init_KOPT
	[ -z "$KOPT_alpine_dev" ] && return 0
	alpine_mounted=
	alpine_dev=${KOPT_alpine_dev%%:*}
	alpine_fs=${KOPT_alpine_dev#*:}
	[ "$alpine_fs" = "$KOPT_alpine_dev" ] && unset alpine_fs
	# first we check if alpine_dev is mounted and use this
	alpine_mnt=$(find_mnt $alpine_dev /proc/mounts)
	if [ -z "$alpine_mnt" ]; then
		# then we check fstab
		alpine_mnt=$(find_mnt /dev/$alpine_dev /etc/fstab)
	else
		alpine_mounted=yes
	fi
	# finally we fallback to /media/<devicename>
	[ -z "$alpine_mnt" ] && alpine_mnt=/media/$alpine_dev
}

start() {
	local modloop= mount_opts= modloop_mounted=
	find_media
	if [ -z "$alpine_dev" ] ; then
		return 0
	fi

	if [ -z "$alpine_mounted" ]; then
		ebegin "Mounting $alpine_mnt"
		[ -n "$alpine_fs" ] && mount_opts="-t $alpine_fs"
		mount $mount_opts /dev/$alpine_dev $alpine_mnt 2>/dev/null
		eend $? || return 1
	fi
	mkdir -p /.modloop /lib

	for modloop in ${alpine_mnt}$KOPT_modloop \
			${alpine_mnt}$KOPT_BOOT_IMAGE.modloop.* \
			${alpine_mnt}$KOPT_BOOT_IMAGE.cmg; do
		[ -f "$modloop" ] || continue
		ebegin "Mounting modloop $modloop"
		mount -o loop,ro $fs_opt $modloop /.modloop \
			&& modloop_mounted=1
		eend $? || return 1
	done
	[ "$modloop_mounted" = "1" ] || return 1

	#use unionfs is available and configured
	if grep -q -w "unionfs$" /proc/filesystems && [ -n "$unionfs_size" ]; then
		ebegin "UnionFS detected. Mounting modloop rw"
		mkdir -p /.modunisonfs/modules /lib/modules
		mount -t tmpfs -o size="$unionfs_size" tmpfs /.modunisonfs/modules
		mount -t unionfs -o dirs=/.modunisonfs/modules=rw:/.modloop/modules=ro unionfs /lib/modules
		eend $? || return 1
	else
		rm -rf /lib/modules && ln -sf /.modloop/modules /lib/
	fi

	# copy firmware if there are any
	if [ -d $alpine_mnt/firmware ]; then
	        ebegin "Copying firmware from $alpine_mnt/firmware"
	        cp -R -a $alpine_mnt/firmware /lib/
	        eend $?
	elif  [ -d /lib/modules/firmware ]; then
		rmdir /lib/firmware 2>/dev/null \
			&& ln -s /lib/modules/firmware /lib/
	fi
	return 0
}

stop() {
	local rc=0
	find_media
	[ -z "$alpine_dev" ] && return 0
	if mountinfo --quiet /.modloop; then
		ebegin "Unmounting /.modloop"
		umount -d /.modloop
		eend $? || return 1
	fi
	if mountinfo --quiet $alpine_mnt; then
		ebegin "Unmounting $alpine_mnt"
		umount $alpine_mnt
		eend $?
	fi
}

