#!/bin/sh

SYSCFG_UBIFS_MNT=/tmp/syscfg
SLOT="$(find_system_slot)"
echo "Active system$SLOT"

get_current_rootfs_label() {
	rootfs_label="rootfs"
	echo "$rootfs_label"
}

mount_no_ubifs_syscfg_mtd() {
	mtd unlock $(get_current_rootfs_label)
	mount -o remount,rw /dev/root /
}

ubifs_error_check_and_recover() {
	local mtdnum

	ubifs_err="$(cat /proc/sys/kernel/ubifs_error)"
	[ -z "$ubifs_err" -o "$ubifs_err" = "0" ] && return 0

	mtdnum=$(($ubifs_err >> 16))
	mtdnum=$(($mtdnum & 0xff))

	echo "erase mtd${mtdnum} to recover ubifs error $ubifs_err"
	mtd erase /dev/mtd${mtdnum}
	echo 0 > /proc/sys/kernel/ubifs_error
	return 0
}
#LYNQ_MODFIY_START for gsw partition
# return 1 on failed 0 for success  
ubifs_volume_support1() {
	mtdpart_idx="$(find_mtd_index rootfs_data)"
	[ -z "$mtdpart_idx" ] && return 1

	# for SDTIM support
	mtdpart_idx_oemapp="$(find_mtd_index oemapp$SLOT-mount)"
	if [ -z "$mtdpart_idx_oemapp" ]
	then
		mtdpart_idx_oemapp="$(find_mtd_index oemapp$SLOT)"
		if [ -z "$mtdpart_idx_oemapp" ]
		then
			# oem_data may has only one partition
			mtdpart_idx_oemapp="$(find_mtd_index oemapp)"
			[ -z "$mtdpart_idx_oemapp" ] && return 1
		fi
	fi

	grep -qs ubifs /proc/filesystems ||  return 1
	echo "suppoert1 found oemapp partition and ubifs support"
	return 0
}
#LYNQ_MODFIY_END for gsw partition

__try_ubifs_syscfg_mount() {
	overlay_mountpoint=$1
	if [ -z $overlay_mountpoint ]
	then
		overlay_mountpoint=/overlay
	fi
	recover_ubifs=0
	[ ! -e /dev/ubi0 ] && ubiattach /dev/ubi_ctrl -m $mtdpart_idx -d 0 || recover_ubifs=1
	if [ $recover_ubifs -eq 0 ]
	then
		ubi0_nod_id=`cat /sys/class/ubi/ubi0/dev | tr -s ":" " "`
		[ ! -e /dev/ubi0 ] && mknod /dev/ubi0 c ${ubi0_nod_id}
		if [ ! -e /sys/class/ubi/ubi0_0/dev ]
		then
			# no volume
			recover_ubifs=1
		else
			# check for "overlay" volume
			ubi0_0_nod_id=`cat /sys/class/ubi/ubi0_0/dev | tr -s ":" " "`
			[ ! -e /dev/ubi0_0 ] && mknod /dev/ubi0_0 c ${ubi0_0_nod_id}
			{ ubinfo /dev/ubi0_0 | grep Name  | grep -qs "overlay" ; } || \
			recover_ubifs=1
		fi
	fi
	if [ $recover_ubifs -eq 1 ]
	then
		echo "ubifs syscfg partition is damaged"
		echo "try to recover by formatting $mtdpart_idx..."
		#[ -e /dev/ubi0 ] && ubidetach -m $mtdpart_idx
		#ubiformat -y -q /dev/mtd$mtdpart_idx
		#ubiattach -m $mtdpart_idx /dev/ubi_ctrl
		ubi0_nod_id=`cat /sys/class/ubi/ubi0/dev | tr -s ":" " "`
		[ ! -e /dev/ubi0 ] && mknod /dev/ubi0 c ${ubi0_nod_id}
#		ubimkvol /dev/ubi0 -n 1 -N etc -t dynamic -s 5MiB
#		ubimkvol /dev/ubi0 -n 2 -N nvm -t dynamic -s 4MiB
#		ubimkvol /dev/ubi0 -n 0 -N overlay -t dynamic --maxavsize
		ubimkvol /dev/ubi0 -n 0 -N syscfg -t dynamic --maxavsize
	fi

	# finally mount the ubifs
#	mount -t ubifs -o noatime ubi0:overlay $overlay_mountpoint || return 1
#	mount -t ubifs -o noatime ubi0:data /mnt || return 1
#	mount -t ubifs -o noatime ubi0:data /log || return 1
#	mount -t ubifs -o noatime ubi0:etc $overlay_mountpoint/etc || return 1
#	mount -t ubifs -o noatime ubi0:nvm $overlay_mountpoint/nvm || return 1
	mount -t ubifs -o noatime ubi0_0 $overlay_mountpoint || return 1

	# clean up uci tmp file to avoid wirtable partition full
	rm -rf $overlay_mountpoint/root/config/.*.uci-*

	return 0
}

try_ubifs_syscfg_mount() {
	__try_ubifs_syscfg_mount || {
		echo "roofs_data mount fail, try to recover by erase..."
		umount $overlay_mountpoint
#		umount $overlay_mountpoint/etc
#		umount /log
#		umount /mnt
#		umount /data
		mtd erase rootfs_data
		__try_ubifs_syscfg_mount
	}

	return 0
}
#LYNQ_MODFIY_START for gsw partition
ubifs_oemapp_mount() {
	recover_ubifs=0
	[ ! -e /dev/ubi1 ] && ubiattach /dev/ubi_ctrl -m $mtdpart_idx_oemapp -d 1 || recover_ubifs=1
	if [ $recover_ubifs -eq 0 ]
	then
		ubi1_nod_id=`cat /sys/class/ubi/ubi1/dev | tr -s ":" " "`
		[ ! -e /dev/ubi1 ] && mknod /dev/ubi1 c ${ubi1_nod_id}
		if [ ! -e /sys/class/ubi/ubi1_0/dev ]
		then
			# no volume
			recover_ubifs=1
		else
			# check for "oemapp" volume
			ubi1_0_nod_id=`cat /sys/class/ubi/ubi1_0/dev | tr -s ":" " "`
			[ ! -e /dev/ubi1_0 ] && mknod /dev/ubi1_0 c ${ubi1_0_nod_id}
			{ ubinfo /dev/ubi1_0 | grep Name  | grep -qs "oemapp" ; } || \
			recover_ubifs=1
		fi
	fi

	if [ $recover_ubifs -eq 1 ]
	then
		echo "err: ubi attach failed, oemapp partition damaged?"
	fi

	mkdir -p /oemapp
	if [ -e /etc/selinux ]
	then
	mount -t ubifs -o ro,noatime,bulk_read,context=u:r:tmp.fs ubi1_0 /oemapp
	else
	mount -t ubifs -o ro,noatime,bulk_read ubi1_0 /oemapp
	fi
	return 0
}

ubifs_oemdata_mount() {
	mtdpart_idx_oemdata="$(find_mtd_index oemdata)"
	[ -z "$mtdpart_idx_oemdata" ] && return 1
	recover_ubifs=0
	[ ! -e /dev/ubi2 ] && ubiattach /dev/ubi_ctrl -m $mtdpart_idx_oemdata -d 2 || recover_ubifs=1
	if [ $recover_ubifs -eq 0 ]
	then
		ubi2_nod_id=`cat /sys/class/ubi/ubi2/dev | tr -s ":" " "`
		[ ! -e /dev/ubi2 ] && mknod /dev/ubi2 c ${ubi2_nod_id}
		if [ ! -e /sys/class/ubi/ubi2_0/dev ]
		then
			# no volume
			recover_ubifs=1
		else
			# check for "oemdata" volume
			ubi2_0_nod_id=`cat /sys/class/ubi/ubi2_0/dev | tr -s ":" " "`
			[ ! -e /dev/ubi2_0 ] && mknod /dev/ubi2_0 c ${ubi2_0_nod_id}
			{ ubinfo /dev/ubi2_0 | grep Name  | grep -qs "oemdata" ; } || \
			recover_ubifs=1
		fi
	fi

	if [ $recover_ubifs -eq 1 ]
	then
		echo "err: ubi attach failed, oemdata partition damaged?"
	fi

	mkdir -p /oemdata
	if [ -e /etc/selinux ]
	then
	mount -t ubifs -o noatime,bulk_read,rw,context=u:r:tmp.fs ubi2_0 /oemdata
	else
	mount -t ubifs -o noatime,bulk_read,rw ubi2_0 /oemdata
	fi
	return 0
}

#LYNQ_MODFIY_END for gsw partition

pivot() { # <new_root> <old_root>
	/bin/mount -o noatime,move /proc $1/proc && \
	pivot_root $1 $1$2 && {
		/bin/mount -o noatime,move $2/dev /dev
		/bin/mount -o noatime,move $2/tmp /tmp
		/bin/mount -o noatime,move $2/sys /sys 2>&-
		/bin/mount -o noatime,move $2/overlay /overlay 2>&-
#		/bin/mount -o ro,noatime,move $2/NVM/oem_data /NVM/oem_data 2>&-
		return 0
	}
}

# /bin/mount -o noatime,lowerdir=/,upperdir=/overlay/root,workdir=/overlay/work -t overlay "overlayfs:/overlay/root" /mnt
fopivot() { # <rw_root> <ro_root> <dupe?>
	/bin/mount -o noatime,lowerdir=/,upperdir=$1,workdir=$2 -t overlay "overlayfs:$1" /mnt
	pivot /mnt $3
}


create_overlay() { # <lowerdir> <upper_dir> <target>
	mkdir -p $1/root $1/work
	
#	/bin/mount -o noatime,lowerdir=$1,upperdir=$2/root,workdir=$2/work -t overlay "overlayfs:$2" $3
	fopivot $1/root $1/work /rom 1
}

ubifs_syscfg_rootfs_pivot() {
	echo "switching to ubifs sysfs overlay"

	mount -o bind / /rom

	# Dir /etc and /NVM can be written after creating overlay
	create_overlay $overlay_mountpoint
#	create_overlay /NVM $overlay_mountpoint/nvm /NVM
	#LYNQ_MODFIY_START for gsw partition
	ubifs_oemapp_mount
	ubifs_oemdata_mount
	source /lib/preinit/emmc_mount.sh
    mkdir -p /media/var/log
	#LYNQ_MODFIY_END for gsw partition
	if [ -e /etc/selinux ] && [ ! -e /etc/selinux/restorecon_stat ]; then
		restorecon -r /mnt /data /log /NVM /system/etc
		echo "/mnt /data /log /NVM /system/etc" >> /etc/selinux/restorecon_stat
	fi
}
#LYNQ_MODFIY_START for gsw partition
do_mount_ubifs_overlay() {
	ubifs_error_check_and_recover
	{ ubifs_volume_support1 && \   
	try_ubifs_syscfg_mount && \
	ubifs_syscfg_rootfs_pivot ; } || mount_no_ubifs_syscfg_mtd
}
#LYNQ_MODFIY_END for gsw partition
boot_hook_add preinit_main do_mount_ubifs_overlay
