#!/bin/sh /etc/rc.common
# Copyright (C) 2006-2011 OpenWrt.org

START=1
STOP=1

#cgroups 配置参数

cpu_guarantee=90 #cpu 占用保证 cpu_guarantee%
mem_usage="800M" #memory 占用上限
memsw_usage="1312M" #默认800M memory + 512M swap占用上限
cpu_limit=99 #cpu 占用上限
cnt_cpu=2 #cpu 核心数
mem_id=0 #内存节点

cgroups_set() {

	if [ -n "$1" ]; then
		cpu_limit=$1 #cpu 占用上限 cpu_usage% 
	fi

	if [ ! -f /sys/fs/cgroup/memory.limit_in_bytes ] ;then
		mount -t cgroup cgroup_root /sys/fs/cgroup
	fi
	
	if [ ! -d /sys/fs/cgroup/controller ] ;then
		mkdir /sys/fs/cgroup/controller
	fi

	# 可用的cpu数量，影响cpu占用率限制值
	local profile_cnt_cpu=`uci -c /etc/profile.d get profile.@eapcontroller[0].available_cpu_num`
	if [ -n "$profile_cnt_cpu" ]; then
		cnt_cpu=$profile_cnt_cpu
	fi
	echo avaliable cpu number: $cnt_cpu > /dev/console

	# cpu满载时，本进程的重要程度
	local profile_cpu_guarantee=`uci -c /etc/profile.d get profile.@eapcontroller[0].cpu_guarantee`
	if [ -n "$profile_cpu_guarantee" ]; then
		echo profile_cpu_guarantee $profile_cpu_guarantee > /dev/console
		cpu_guarantee=$profile_cpu_guarantee
	fi
	echo cpu guarantee: $cpu_guarantee > /dev/console

	cpu_time_schedule_period=`cat /sys/fs/cgroup/controller/cpu.cfs_period_us` #cfs 一次调度周期，默认 100000 us
	cpu_time_limit_in_one_schedule_period=`expr ${cpu_time_schedule_period} \* ${cnt_cpu} \* ${cpu_limit} / 100` # cfs 调度过程中，controller组下面进程使用的 cpu 时间上限
	echo ${cpu_time_limit_in_one_schedule_period} > /sys/fs/cgroup/controller/cpu.cfs_quota_us

	radio=`expr 100 - ${cpu_guarantee}`
	importance_other=`cat /sys/fs/cgroup/cpu.shares`
	importance_controller=`expr ${importance_other} \* ${cpu_guarantee} / ${radio})` 
	#controller 进程组的重要程度，标识在 cpu 满载时，controller进程组被分配cpu资源的多少，other进程组和controller进程组cpu占比为 importance_other/importance_controller
	echo ${importance_controller} > /sys/fs/cgroup/controller/cpu.shares

	# 用于限制进程在某个核运行
	local cpu_id=`uci -c /etc/profile.d get profile.@eapcontroller[0].available_cpu_id`
	if [ -n "$cpu_id" ]; then
		echo cpu id: $cpu_id > /dev/console
		echo $cpu_id > /sys/fs/cgroup/controller/cpuset.cpus
		
	fi

	local profile_mem_id=`uci -c /etc/profile.d get profile.@eapcontroller[0].available_mem_id`
	if [ -n "$profile_mem_id" ]; then
		echo profile_mem_id $profile_mem_id > /dev/console
		mem_id=$profile_mem_id
	fi
	echo $mem_id > /sys/fs/cgroup/controller/cpuset.mems

	# 用于限制进程的内存使用大小
	if [ -z "$2" ]; then
		local profile_mem_usage=`uci -c /etc/profile.d get profile.@eapcontroller[0].mem_usage_limit`
		if [ -n "$profile_mem_usage" ]; then
			mem_usage=$profile_mem_usage
		fi
	else
		mem_usage=$2
	fi

	echo mem usage limit: $mem_usage > /dev/console
	echo ${mem_usage} > /sys/fs/cgroup/controller/memory.limit_in_bytes

	# 用于限制进程的内存+SWAP空间使用大小
	if [ -z "$3" ]; then
		local profile_memsw_usage=`uci -c /etc/profile.d get profile.@eapcontroller[0].memsw_usage_limit`
		if [ -n "$profile_memsw_usage" ]; then
			memsw_usage=$profile_memsw_usage
		fi
	else
		memsw_usage=$3
	fi

	echo memsw usage limit: $memsw_usage > /dev/console
	echo ${memsw_usage} > /sys/fs/cgroup/controller/memory.memsw.limit_in_bytes

	current_pid=""
	count=0
	current_pid=`cat /sys/fs/cgroup/controller/cgroup.procs`

	if [ $? -eq 0 ]; then
		for i in $current_pid
		do
			if [ "$i" -gt 0 ]; then
				let count++
			fi
		done
		if [ "$count" -ge 3 ]; then
			echo "already set cgroup.procs, cgroups set done" > /dev/console
			exit 0
		fi
	fi

	time1=0
	pid1=`pgrep -o local-starter`
	while [ ! -n "$pid1" -a "$time1" -le 60 ]
	do
		echo "wait for local-starter/controller..."
		sleep 1s
		let "time1++"
		pid1=`pgrep -o local-starter`
	done
	if [ -n "$pid1" ]; then
		echo ${pid1} >> /sys/fs/cgroup/controller/cgroup.procs
	fi

	time2=0
	pid2=`pgrep -o mongod`
	while [ ! -n "$pid2" -a "$time2" -le 20 ]
	do
		echo "wait for mongodb..."
		sleep 3s
		let "time2++"
		pid2=`pgrep -o mongod`
	done
	if [ -n "$pid2" ]; then
		echo ${pid2} >> /sys/fs/cgroup/controller/cgroup.procs
	fi

	echo "cgroups set done"
}


start() {
	factory_mode=`uci get factory_mode.factory_mode.factory_flag`
	local STRAT_CMD_PATH="/opt/tplink/EAPController/properties/omada.properties"
	if [ $factory_mode == 1 ]; then
		echo "Invalid signature or device is on testing, will not start eapcontroller ..." > /dev/console
		#return 1
	fi

	echo 0 > /proc/sys/kernel/sched_autogroup_enabled

	mkdir -p /tmp/poifiles
	mkdir -p /opt/tplink/EAPController/data/logs/
	pkill mongod >/dev/null 2>&1	
	#如果omada.properties中start.cmd存在则作为controller启动参数
	start_cmd=`cat $STRAT_CMD_PATH | grep "starter.cmd" | awk -F'=' '{print substr($0,index($0,"=")+1)}'`
	if [ -n "$start_cmd" ]; then
		cd /opt/tplink/EAPController/lib
		echo "#!/bin/sh" > /tmp/omada_start.sh
		echo $start_cmd >> /tmp/omada_start.sh
		chmod a+x /tmp/omada_start.sh
		/tmp/omada_start.sh
		if [ -n "$1" ]; then
			cgroups_set $1 $2 &
		fi
		return
	fi


	
	# 设置java运行的默认参数,Xmx_para,Xms_para
	local size_limit=1024000
	local profile_Xmx_para=`uci -c /etc/profile.d get profile.@eapcontroller[0].java_mem_max`
	if [ -n "$profile_Xmx_para" ]; then
		size_limit=$profile_Xmx_para
	fi
	echo java memory size limit: $size_limit > /dev/console
	
	# 根据剩余内存的大小决定是否按照配置的参数启动java
	mem_size=`free | awk '/Mem/ {print $4}'`
	echo mem_size $mem_size > /dev/console
	if [ $mem_size -ge $((size_limit)) ]; then
		Xmx_para=-Xmx$((size_limit/1000))m
	else
		Xmx_para=-Xmx512m
	fi

	local least_size_limit=512000
	local profile_Xms_para=`uci -c /etc/profile.d get profile.@eapcontroller[0].java_mem_least`
	if [ -n "$profile_Xms_para" ]; then
		least_size_limit=$profile_Xms_para
	fi
	Xms_para=-Xms$((least_size_limit/1000))m
	echo Xmx_para: $Xmx_para Xms_para: $Xms_para > /dev/console

	omada_ver=3
	if [ -f /opt/tplink/EAPController/omadacVersion ] ; then
		omada_ver=`cat /opt/tplink/EAPController/omadacVersion | grep -o  -e "^[0-9]"`
 	fi

	echo "Starting eapconroller ..." > /dev/console

	cd /opt/tplink/EAPController/lib

	if [ 5 -le $omada_ver ] ; then
		vnete java -server -Xverify:none $Xms_para $Xmx_para -XX:MaxHeapFreeRatio=60 -XX:MinHeapFreeRatio=30 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/tplink/EAPController/data/logs/java_heapdump.hprof -Djava.home="/" -cp "/opt/tplink/EAPController/lib/*:/opt/tplink/EAPController/properties" com.tplink.smb.omada.starter.OmadaLinuxMain start > /opt/tplink/EAPController/data/logs/startup.log 2>&1 &
	elif [ 4 -le $omada_ver ] ; then
		Xms_para=-Xms128m
		vnete java -server $Xms_para $Xmx_para -XX:MaxHeapFreeRatio=60 -XX:MinHeapFreeRatio=30 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/tplink/EAPController/data/logs/java_heapdump.hprof -Djava.home="/" -cp "/opt/tplink/EAPController/lib/*" com.tplink.omada.start.OmadaLinuxMain start > /opt/tplink/EAPController/data/logs/startup.log 2>&1 &
 	else
		vnete java -server -Xms128m $Xmx_para -XX:MaxHeapFreeRatio=60 -XX:MinHeapFreeRatio=30 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/tplink/EAPController/data/logs/java_heapdump.hprof -Deap.home="/opt/tplink/EAPController" -Djava.home="/" -cp "/opt/tplink/EAPController/lib/*" com.tp_link.eap.start.EapLinuxMain start > /opt/tplink/EAPController/data/logs/startup.log 2>&1 &
		Xms_para=-Xms128m
		vnete java -server $Xms_para $Xmx_para -XX:MaxHeapFreeRatio=60 -XX:MinHeapFreeRatio=30 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/tplink/EAPController/data/logs/java_heapdump.hprof -Deap.home="/opt/tplink/EAPController" -Djava.home="/" -cp "/opt/tplink/EAPController/lib/*" com.tp_link.eap.start.EapLinuxMain start > /opt/tplink/EAPController/data/logs/startup.log 2>&1 &
 	fi

	if [ -n "$1" ]; then
		cgroups_set $1 $2 &
	fi
}

stop() {
	echo "Stopping eapconroller ..."

	pid1=`pgrep -o local-starter`
	pid2=`pgrep -o mongod`

	if [ -n "$pid1" ];then
		kill -9 $pid1
	fi

	if [ -n "$pid2" ];then
		kill -9 $pid2
	fi
}

restart() {
	stop
	sleep 10s
	start  $1 $2
}

boot() {
	crontabs_check=`cat /etc/crontabs/root | grep eapcontroller-log-clean`
	if [ -z "$crontabs_check" ]; then
		echo "*/10 * * * * eapcontroller-log-clean" >> /etc/crontabs/root
	fi
	
	# disable transparent_hugepage by mongodb, see https://docs.mongodb.com/manual/tutorial/transparent-huge-pages/
	if test -f /sys/kernel/mm/transparent_hugepage/enabled; then
		echo never >  /sys/kernel/mm/transparent_hugepage/enabled
	fi
	if test -f /sys/kernel/mm/transparent_hugepage/defrag; then
		echo never >  /sys/kernel/mm/transparent_hugepage/defrag
	fi
	
	local pid=`pgrep -o local-starter`

	if [ ! -f "/opt/tplink/EAPController/data/controller_is_configured" -a -z "$pid" ]; then
		start
		factory_mode=`uci get factory_mode.factory_mode.factory_flag`
		if [ $factory_mode == 1 ]; then
			echo 1
			#return 1
		fi
		local cgroups_set_delay=`uci -c /etc/profile.d get profile.@eapcontroller[0].cgroups_set_delay`
		if [ -n "$cgroups_set_delay" ]; then
			echo "cgroups set delay" >/dev/console
		else
			# cpu占用率限制
			local profile_cpu_limit=`uci -c /etc/profile.d get profile.@eapcontroller[0].cpu_limit_factory`
			if [ -n "$profile_cpu_limit" ]; then
				cpu_limit=$profile_cpu_limit
			fi
			echo cpu_limit: $cpu_limit >/dev/console
			cgroups_set $cpu_limit &
		fi
	fi
}

