# Overlay /proc, /sys with McKernel specific contents

#
# Revert any state that has been initialized before the error occured.
#
if [ -z "$(declare -f error_exit)" ]; then
error_exit() {
	local status=$1

	case $status in
	mcos_sys_mounted)
		if [ "$enable_mcoverlay" == "yes" ]; then
			umount /tmp/mcos/mcos0_sys
		fi
		;&
	mcos_proc_mounted)
		if [ "$enable_mcoverlay" == "yes" ]; then
			umount /tmp/mcos/mcos0_proc
		fi
		;&
	mcoverlayfs_loaded)
		if [ "$enable_mcoverlay" == "yes" ]; then
			rmmod mcoverlay 2>/dev/null
		fi
		;&
	linux_proc_bind_mounted)
		if [ "$enable_mcoverlay" == "yes" ]; then
			umount /tmp/mcos/linux_proc
		fi
		;&
	tmp_mcos_mounted)
		if [ "$enable_mcoverlay" == "yes" ]; then
			umount /tmp/mcos
		fi
		;&
	tmp_mcos_created)
		if [ "$enable_mcoverlay" == "yes" ]; then
			rm -rf /tmp/mcos
		fi
		;&
	initial)
		# Nothing more to revert
		;;
	esac

	exit 1
}
fi

if [ ! -e /tmp/mcos ]; then 
    mkdir -p /tmp/mcos; 
fi
if ! mount -t tmpfs tmpfs /tmp/mcos; then
    echo "error: mount /tmp/mcos" >&2
    error_exit "tmp_mcos_created"
fi
if [ ! -e /tmp/mcos/linux_proc ]; then 
    mkdir -p /tmp/mcos/linux_proc; 
fi
if ! mount --bind /proc /tmp/mcos/linux_proc; then
    echo "error: mount /tmp/mcos/linux_proc" >&2
    error_exit "tmp_mcos_mounted"
fi
if ! taskset -c 0 insmod @KMODDIR@/mcoverlay.ko 2>/dev/null; then
    echo "error: inserting mcoverlay.ko" >&2
    error_exit "linux_proc_bind_mounted"
fi
while [ ! -e /proc/mcos0 ]
do
    sleep 0.1
done
if [ ! -e /tmp/mcos/mcos0_proc ]; then 
    mkdir -p /tmp/mcos/mcos0_proc; 
fi
if [ ! -e /tmp/mcos/mcos0_proc_upper ]; then 
    mkdir -p /tmp/mcos/mcos0_proc_upper; 
fi
if [ ! -e /tmp/mcos/mcos0_proc_work ]; then 
    mkdir -p /tmp/mcos/mcos0_proc_work; 
fi
if ! mount -t mcoverlay mcoverlay -o lowerdir=/proc/mcos0:/proc,upperdir=/tmp/mcos/mcos0_proc_upper,workdir=/tmp/mcos/mcos0_proc_work,nocopyupw,nofscheck /tmp/mcos/mcos0_proc; then
    echo "error: mounting /tmp/mcos/mcos0_proc" >&2
    error_exit "mcoverlayfs_loaded"
fi
# TODO: How de we revert this in case of failure??
mount --make-rprivate /proc

while [ ! -e /sys/devices/virtual/mcos/mcos0/sys/setup_complete ]
do
    sleep 0.1
done
if [ ! -e /tmp/mcos/mcos0_sys ]; then 
    mkdir -p /tmp/mcos/mcos0_sys; 
fi
if [ ! -e /tmp/mcos/mcos0_sys_upper ]; then 
    mkdir -p /tmp/mcos/mcos0_sys_upper; 
fi
if [ ! -e /tmp/mcos/mcos0_sys_work ]; then 
    mkdir -p /tmp/mcos/mcos0_sys_work; 
fi
if ! mount -t mcoverlay mcoverlay -o lowerdir=/sys/devices/virtual/mcos/mcos0/sys:/sys,upperdir=/tmp/mcos/mcos0_sys_upper,workdir=/tmp/mcos/mcos0_sys_work,nocopyupw,nofscheck /tmp/mcos/mcos0_sys; then
    echo "error: mount /tmp/mcos/mcos0_sys" >&2
    error_exit "mcos_proc_mounted"
fi
# TODO: How de we revert this in case of failure??
mount --make-rprivate /sys

touch /tmp/mcos/mcos0_proc/mckernel

rm -rf /tmp/mcos/mcos0_sys/setup_complete

# Hide NUMA related files which are outside the LWK partition
for cpuid in `find /sys/devices/system/cpu/* -maxdepth 0 -name "cpu[0123456789]*" -printf "%f "`; do
    if [ ! -e "/sys/devices/virtual/mcos/mcos0/sys/devices/system/cpu/$cpuid" ]; then
	rm -rf /tmp/mcos/mcos0_sys/devices/system/cpu/$cpuid
	rm -rf /tmp/mcos/mcos0_sys/bus/cpu/devices/$cpuid
	rm -rf /tmp/mcos/mcos0_sys/bus/cpu/drivers/processor/$cpuid
    else
	for nodeid in `find /sys/devices/system/cpu/$cpuid/* -maxdepth 0 -name "node[0123456789]*" -printf "%f "`; do
	    if [ ! -e "/sys/devices/virtual/mcos/mcos0/sys/devices/system/cpu/$cpuid/$nodeid" ]; then
		rm -f /tmp/mcos/mcos0_sys/devices/system/cpu/$cpuid/$nodeid
	    fi
	done
    fi
done
for nodeid in `find /sys/devices/system/node/* -maxdepth 0 -name "node[0123456789]*" -printf "%f "`; do
    if [ ! -e "/sys/devices/virtual/mcos/mcos0/sys/devices/system/node/$nodeid" ]; then
	rm -rf /tmp/mcos/mcos0_sys/devices/system/node/$nodeid/*
	rm -rf /tmp/mcos/mcos0_sys/bus/node/devices/$nodeid
    else
	# Delete non-existent symlinks
	for cpuid in `find /sys/devices/system/node/$nodeid/* -maxdepth 0 -name "cpu[0123456789]*" -printf "%f "`; do
	    if [ ! -e "/sys/devices/virtual/mcos/mcos0/sys/devices/system/node/$nodeid/$cpuid" ]; then
		rm -f /tmp/mcos/mcos0_sys/devices/system/node/$nodeid/$cpuid
	    fi
	done

	rm -f /tmp/mcos/mcos0_sys/devices/system/node/$nodeid/memory*
    fi
done
rm -f /tmp/mcos/mcos0_sys/devices/system/node/has_*
for cpuid in `find /sys/bus/cpu/devices/* -maxdepth 0 -name "cpu[0123456789]*" -printf "%f "`; do
    if [ ! -e "/sys/devices/virtual/mcos/mcos0/sys/bus/cpu/devices/$cpuid" ]; then
	rm -rf /tmp/mcos/mcos0_sys/bus/cpu/devices/$cpuid
    fi
done
