#!/bin/sh
# Copyright (c) 2000-2014 Synology Inc. All rights reserved.

# linuxrc.syno will go into junior mode or active mode(mount md0 and switch_root) depend on the return value
# 0: active mode, 1: junior mode
# it will block in this script for passive mode

echo "START AHAtasks, action is '$1'"

SYNOINFO_DEF="/etc.defaults/synoinfo.conf"
. /etc.defaults/rc.subr
. /etc.defaults/rc.fan
. /etc.defaults/rc.sas
. /etc/rc.network_dualhead

# adjust message queue
dual_head_adjust_msg_queue

# KERNEL_VCODE is needed for detect_manufactory_device
KERNEL_VCODE=`KernelVersionCode $(KernelVersion)`

TIME_TO_CHECK_IF_GO_INTO_NEXT_STAGE=1
DUAL_GLIBC_PATH=/dual_glibc
TMP_AHA="/tmp/aha"
EXEC_BINARY="/usr/sbin/chroot $DUAL_GLIBC_PATH"
SYNOAHA_ETC_DEFAULTS_DIR="/usr/syno/etc.defaults/synoaha"
SYNOAHA_BIN_DIR="/usr/syno/synoaha/bin"
BIN_SYNOAHASTR="$SYNOAHA_BIN_DIR/synoahastr"
BIN_SYNOAHA="$SYNOAHA_BIN_DIR/synoaha"
GO_INTO_ACTIVE_MODE=$DUAL_GLIBC_PATH/`$EXEC_BINARY $BIN_SYNOAHASTR --go-into-active-mode`
GO_INTO_JUNIOR_MODE=$DUAL_GLIBC_PATH/`$EXEC_BINARY $BIN_SYNOAHASTR --go-into-junior-mode`
REBOOT=$DUAL_GLIBC_PATH/`$EXEC_BINARY $BIN_SYNOAHASTR --reboot`
POWEROFF=$DUAL_GLIBC_PATH/`$EXEC_BINARY $BIN_SYNOAHASTR --poweroff`
PASSIVE_ROLE_FOR_SCEMD=$DUAL_GLIBC_PATH/`$EXEC_BINARY $BIN_SYNOAHASTR --passive-role-for-scemd`
PASSIVE_WEB_SERVER=$DUAL_GLIBC_PATH/`$EXEC_BINARY $BIN_SYNOAHASTR --enable-web-server`
PASSIVE_WEB_SERVER_DISABLE=$DUAL_GLIBC_PATH/`$EXEC_BINARY $BIN_SYNOAHASTR --disable-web-server`
RESTART_HA_MGR_DAEMON=$DUAL_GLIBC_PATH/`$EXEC_BINARY $BIN_SYNOAHASTR --restart-ha-mgr-daemon`
NET_DRIVERS="dca e1000e i2c-algo-bit igb be2net ixgbe tn40xx i40e compat mlx_compat mlx4_core mlx4_en mlx5_core mdio libcrc32c bnx2x"
SYNOBOOT3_MOUNT_POINT=`$EXEC_BINARY $BIN_SYNOAHASTR --synoboot3-mount-point`
DUAL_VAR_LOG="$DUAL_GLIBC_PATH/var/log"
FILE_GETTY_PID="/tmp/getty.pid"
SSHKEYGEN="/usr/bin/ssh-keygen"
AHA_MGR_DAEMON=`$EXEC_BINARY $BIN_SYNOAHASTR --syno-aha-mgr-daemon`
AHA_COMM_DAEMON=`$EXEC_BINARY $BIN_SYNOAHASTR --syno-aha-comm-daemon`
AHA_DAEMON="syno_aha_daemon"
AHA_DAEMON_STATIC="syno_aha_daemon_static"
BIN_AHA_MGR_DAEMON="$SYNOAHA_BIN_DIR/$AHA_MGR_DAEMON"
BIN_AHA_COMM_DAEMON="$SYNOAHA_BIN_DIR/$AHA_COMM_DAEMON"
BIN_AHA_DAEMON="$SYNOAHA_BIN_DIR/$AHA_DAEMON"
BIN_AHA_DAEMON_STATIC="$SYNOAHA_BIN_DIR/$AHA_DAEMON_STATIC"
PASSIVE_SCRIPT="$SYNOAHA_ETC_DEFAULTS_DIR/AHAPassive.sh"

BIN_SCEMD="/usr/syno/bin/scemd"
CHECK_ROUTE_IN_PASSIVE="check_route_in_passive"
BIN_CHECK_ROUTE_PASSIVE="/usr/syno/bin/$CHECK_ROUTE_IN_PASSIVE"

FILE_DAEMON_LIST="/tmp/.aha_daemon_list"

##################################################
# Exit ret define
exit_become_active=0
exit_not_support_sas=1
exit_no_disks=2
exit_manufactory_dev_detected=3
exit_unknown_err=99
exit_go_into_junior_mode=100
exit_reboot=101
exit_poweroff=102

exit_stop_process=255  # will not exit
##################################################

##################################################
# stage
stage_check="check_stage"
stage_junior="junior_stage"
##################################################

kill_dhcp_processes()
{
	local ifn=$1
	local dhcp
	local input_str
	local pid
	local all_dhcp_processes="udhcpc dhcpcd dhcp6c"

	for dhcp in ${all_dhcp_processes}; do
		# FIXME: use awk if awk is supported in junior mode in the future
		input_str=`ps | grep ${dhcp} | grep ${ifn}`
		pid=`echo $input_str | cut -d ' ' -f 1`
		if [ -n "${pid}" ]; then
			kill -s SIGTERM ${pid}
			kill -s SIGKILL ${pid}
		fi
	done
}

kill_process_with_term()
{
	local input_str="$DUAL_GLIBC_PATH/bin/ps auxw"
	local result=""
	local term=""
	local pid=""

	if [ 0 -eq $# ]; then
		exit 0
	fi

	for term in $@; do
		input_str="$input_str | grep $term"
	done
	input_str="$input_str | grep -v grep | grep -v \"Z*\[*\]\""
	while [ 1 ]; do
		result=`eval $input_str`

		pid=`echo $result | cut -d ' ' -f 2`
		if [ "$pid" != "" ]; then
			kill -s SIGTERM $pid
			kill -s SIGKILL $pid
		else
			break
		fi
	done
}

# The total waiting time is $WAIT_COUNT_MAX
kill_and_wait_process()
{
	local STOP_REASON=0
	local PROCESS_LIST=""
	local PROCESS_PID=0
	local process_status="S"
	local ZOMBIE_STATUS="Z"
	local WAIT_COUNT_MAX=100
	local counter=0

	STOP_REASON=$1
	shift
	PROCESS_LIST=$@

	echo "================ start to killall process"
	# killall daemon
	for daemon in ${PROCESS_LIST}
	do
		killall $daemon
	done

	echo "================ start to wait process terminated"
	# check if all the daemons have terminated
	for daemon in ${PROCESS_LIST}
	do
		PROCESS_PID=0
		PROCESS_PID=`$EXEC_BINARY /bin/pidof $daemon`
		if [ "$PROCESS_PID" = "" ]; then
			continue
		fi

		echo "================ wait $daemon, pid=$PROCESS_PID"
		# wait until daemon is terminated
		for pid in ${PROCESS_PID}
		do
			# prolong expander HB timer to let remote realize that local host is online
			if [ $exit_reboot -ne $STOP_REASON -a $exit_poweroff -ne $STOP_REASON ]; then
				$EXEC_BINARY $BIN_SYNOAHA --set_all_expander_HB_timer `expr $WAIT_COUNT_MAX + 20`
			fi
			while [ 1 ]; do
				process_status="S"
				process_status=`$EXEC_BINARY cat /proc/$pid/stat | $EXEC_BINARY awk '{print $3}'`
				if [ "$process_status" = "$ZOMBIE_STATUS" -o "$process_status" = "" ]; then
					break
				fi
				if [ $counter -ge $WAIT_COUNT_MAX ]; then
					echo "Timeout to wait $daemon stop, force to kill"
					kill -s SIGKILL $pid
					break
				fi
				counter=`expr $counter + 1`
				sleep 1
			done
		done
	done
	# prolong expander HB timer to let remote realize that local host is online
	if [ $exit_reboot -ne $STOP_REASON -a $exit_poweroff -ne $STOP_REASON ]; then
		$EXEC_BINARY $BIN_SYNOAHA --set_all_expander_HB_timer 300
	fi
}

GenerateSSHKeyAndRunSSH()
{
	{
        if [ -x "$DUAL_GLIBC_PATH/$SSHKEYGEN" ]; then
			if [ ! -d $DUAL_GLIBC_PATH/etc/ssh ]; then
				$EXEC_BINARY mkdir -p /etc/ssh
			fi
			$EXEC_BINARY $SSHKEYGEN -A
		fi
		$EXEC_BINARY /usr/bin/sshd &
	}&
}

mount_fs()
{
	[ -d $DUAL_GLIBC_PATH/dev ] || cp -r /dev/ $DUAL_GLIBC_PATH/
	rm -f $DUAL_GLIBC_PATH/dev/log
	cp -rf /etc/* $DUAL_GLIBC_PATH/etc/
	[ -L $DUAL_GLIBC_PATH/etc.defaults ] || ln -s /etc $DUAL_GLIBC_PATH/etc.defaults
	[ -d $DUAL_GLIBC_PATH/lib/modules ] || mkdir $DUAL_GLIBC_PATH/lib/modules
	cp -rf /lib/modules/* $DUAL_GLIBC_PATH/lib/modules
	[ -d $DUAL_GLIBC_PATH/proc ] || mkdir $DUAL_GLIBC_PATH/proc
	[ -d $DUAL_GLIBC_PATH/sys ] || mkdir $DUAL_GLIBC_PATH/sys
	[ -d $DUAL_GLIBC_PATH/tmp ] || mkdir $DUAL_GLIBC_PATH/tmp
	[ -d $DUAL_GLIBC_PATH/run ] || mkdir $DUAL_GLIBC_PATH/run
	[ -d $DUAL_GLIBC_PATH/mnt ] || mkdir $DUAL_GLIBC_PATH/mnt
	[ -d $DUAL_VAR_LOG ] || mkdir $DUAL_VAR_LOG
	[ -d $DUAL_VAR_LOG/synolog ] || mkdir $DUAL_VAR_LOG/synolog
	$EXEC_BINARY mount -t proc /proc /proc
	$EXEC_BINARY mount -t sysfs /sys /sys
	$EXEC_BINARY mount -t devtmpfs devtmpfs /dev
	# work arround now
	[ -d $DUAL_GLIBC_PATH/dev/pts ] || mkdir -p $DUAL_GLIBC_PATH/dev/pts
	$EXEC_BINARY mount -vt devpts -o gid=4,mode=620 none /dev/pts
	$EXEC_BINARY echo "/@%e.core" >> /proc/sys/kernel/core_pattern
	$EXEC_BINARY mkdir -p $SYNOBOOT3_MOUNT_POINT
	$EXEC_BINARY $BIN_SYNOAHA --mount-synoboot3 $SYNOBOOT3_MOUNT_POINT
	$EXEC_BINARY mkdir -p $SYNOBOOT3_MOUNT_POINT/log
	$EXEC_BINARY mkdir -p $SYNOBOOT3_MOUNT_POINT/log/synolog
	[ -L $DUAL_GLIBC_PATH/usr/syno/etc.defaults ] || $EXEC_BINARY ln -s /usr/syno/etc /usr/syno/etc.defaults
	# 0: defaul, will NOT reboot; x: will reboot after x seconds
	echo "3" > /proc/sys/kernel/panic
	ulimit -c unlimited
	/bin/echo 65536 > /proc/sys/vm/min_free_kbytes

	# FIXME: copy from upstart-1.x/synoconf/root-file-system.conf
	[ -d $DUAL_GLIBC_PATH/run/synosdk ] || mkdir -m 0755 $DUAL_GLIBC_PATH/run/synosdk
	[ -d $DUAL_GLIBC_PATH/run/synosdk/lock ] || mkdir -m 0777 $DUAL_GLIBC_PATH/run/synosdk/lock
}

umount_fs()
{
	$EXEC_BINARY $PASSIVE_SCRIPT write_log_to_synoboot3
	$EXEC_BINARY umount /dev/pts
	$EXEC_BINARY umount /dev
	$EXEC_BINARY umount /sys
	# save log into synoboot3
	$EXEC_BINARY umount $SYNOBOOT3_MOUNT_POINT
	$EXEC_BINARY umount /proc
}

load_necessary_module()
{
	SYNOLoadModules synobios sg usb-storage
	SYNOLoadAdt7490
	$EXEC_BINARY /bin/mknod /dev/synobios c 201 0
}

unload_necessary_module()
{
	SYNOUnloadAdt7490
	SYNOUnloadModules usb-storage sg
	if [ $exit_reboot -ne $1 -a $exit_poweroff -ne $1 ]; then
		# for reboot or powerof, it needs synobios to finish task
		# no need to unload synobios
		/sbin/rmmod `/sbin/lsmod | /usr/bin/cut -f 1 -d ' ' | /bin/grep synobios`
	fi
}

network_start_junior()
{
	SYNOLoadModules ${NET_DRIVERS}
}

network_start()
{
	SYNOLoadModules ${NET_DRIVERS}
	/usr/syno/bin/synonetseqadj
	/etc/rc.network start
}

network_stop()
{
	/etc/rc.network stop
	# if net driver is unloaded here, WOL will not work after poweroff
	if [ ! -f "$POWEROFF" ]; then
		SYNOUnloadModules ${NET_DRIVERS}
	fi
}

prepare_syslog_ng_environment()
{
	# check /dev/log is a domain socket file
	# prevent error='Address already in use (98)'
	DEV_LOG_FILE_TYPE=`$EXEC_BINARY find /dev/log -type s 2>/dev/null`
	if [ "/dev/log" != "$DEV_LOG_FILE_TYPE" ]; then
		rm -f $DUAL_GLIBC_PATH/dev/log
	fi

	mkdir -p $DUAL_GLIBC_PATH/etc/syslog-ng/patterndb.d

	# init synolog database, then set owner to system:log
	# synolog sometimes will be root:root after upgraded from DSM 5.2 ...
	# this commit is a workaround because root cause is unknown
	SYNOLOG_FOLDER="$DUAL_GLIBC_PATH/var/log/synolog"
	SYNOLOG_DBS=".SYNOCONNDB .SYNOSYSDB"

	if [ ! -d "$SYNOLOG_FOLDER" ]; then
		mkdir -p "$SYNOLOG_FOLDER" -m750
		for db in $SYNOLOG_DBS; do
			touch "$SYNOLOG_FOLDER/$db"
		done
	else
		chmod 750 "$SYNOLOG_FOLDER"
	fi
	chown -R system:log "$SYNOLOG_FOLDER"

	mkdir -p $DUAL_GLIBC_PATH/etc/logrotate.d
	mkdir -p $DUAL_GLIBC_PATH/etc/syslog-ng/patterndb.d/include/not2msg
	mkdir -p $DUAL_GLIBC_PATH/etc/syslog-ng/patterndb.d/include/not2kern

	mkdir -p $DUAL_GLIBC_PATH/usr/local/etc/logrotate.d
	mkdir -p $DUAL_GLIBC_PATH/usr/local/etc/syslog-ng/patterndb.d/synolog
	mkdir -p $DUAL_GLIBC_PATH/usr/local/etc/syslog-ng/patterndb.d/include/not2msg
	mkdir -p $DUAL_GLIBC_PATH/usr/local/etc/syslog-ng/patterndb.d/include/not2kern
}

necessary_daemon_start()
{
	prepare_syslog_ng_environment
	$EXEC_BINARY /usr/bin/syslog-ng -F --worker-threads=`grep -c '^[Pp]rocessor' /proc/cpuinfo` &
	$EXEC_BINARY $PASSIVE_SCRIPT monitor_var_log_rotate &
	if [ $stage_check = $1 ]; then
		GenerateSSHKeyAndRunSSH
		/sbin/syslogd -S
		echo "Please chroot to dual_glibc and see /var/log/kern.log for kernel log." > /var/log/kern.log
		/sbin/getty 115200 console &
		# start udevd
		# FIXME: copy from udevd.upstart
		$EXEC_BINARY /lib/udev/script/syno_default_env.sh gen-rule-file
		$EXEC_BINARY /usr/bin/udevd --daemon
		# resend disk add events that are missed before udev start
		$EXEC_BINARY /usr/bin/udevadm trigger --action=add --subsystem-nomatch=tty
		# end of start udevd
		local pid=`ps | grep getty | grep -v grep`; echo $pid | cut -d' ' -f1 > $FILE_GETTY_PID
		$EXEC_BINARY $BIN_SYNOAHA --self-check

		echo -e "syslogd\nudevd\ngetty" >> $FILE_DAEMON_LIST
	fi
	$EXEC_BINARY $PASSIVE_SCRIPT monitor_synoboot3 &
	echo "Starting to run HA manager"
	$EXEC_BINARY $BIN_AHA_MGR_DAEMON $1 &

	echo -e "syslog-ng\n$AHA_MGR_DAEMON\n$AHA_COMM_DAEMON" >> $FILE_DAEMON_LIST
}

necessary_daemon_stop()
{
	local DAEMON_LIST=""

	kill_process_with_term synoaha sync-time
	kill_process_with_term synoenc update_snap_shot
	kill_process_with_term sshd
	kill_process_with_term AHAPassive.sh monitor_synoboot3
	kill_process_with_term AHAPassive.sh monitor_var_log_rotate
	if [ -f $FILE_GETTY_PID ]; then
		kill -s SIGKILL `cat $FILE_GETTY_PID`
	fi

	for deamon in $(cat $FILE_DAEMON_LIST); do
		DAEMON_LIST="$DAEMON_LIST $deamon"
	done

	kill_and_wait_process $1 $DAEMON_LIST

	rm -f $FILE_DAEMON_LIST
}

prepare_scemd_environment()
{
	$EXEC_BINARY /bin/sh <<'EOF'
	SYNOINFO_DEF="/etc.defaults/synoinfo.conf"
	. /etc.defaults/rc.fan
	SoftLink7490fanInput
EOF
}

start_scemd()
{
	prepare_scemd_environment
	$EXEC_BINARY $BIN_SCEMD
	echo "scemd" >> $FILE_DAEMON_LIST
}

prepare_passive_web_server()
{
	echo "Monitor AHA routing table"
	$EXEC_BINARY $BIN_SYNOAHA --monitor-route-all &
	echo "Monitor Rtnetlink"
	[ -x $BIN_CHECK_ROUTE_PASSIVE ] || ln -s $BIN_SCEMD $BIN_CHECK_ROUTE_PASSIVE
	$BIN_CHECK_ROUTE_PASSIVE &
	echo "Run udhcpd..."
	dhcp_interfaces=`cat /proc/net/dev | grep eth | cut -d: -f 1`
	if [ -x /sbin/udhcpc ]; then
		for dhcpif in ${dhcp_interfaces}
		do
			ifconfig ${dhcpif} 0.0.0.0 up
			udhcp_flags="-p /etc/dhcpc/dhcpcd-${dhcpif}.pid -b -h \"`hostname`\""
			${dhcp_program:-/sbin/udhcpc} -i ${dhcpif} ${udhcp_flags}
			sleep 1;
		done
	fi
	echo "Starting findhostd in flash_rd..."
	/usr/syno/bin/findhostd
	echo "Starting httpd..."
	/usr/sbin/httpd -p 5000 -c /usr/syno/web/httpd.conf
	/usr/sbin/httpd -p 80 -c /usr/syno/web/httpd.conf
	# FIXME: workarround now, wait for udhcp set ip
	sleep 5
	$EXEC_BINARY $BIN_SYNOAHA --net-status-changed
}

reset_passive_web_server()
{
	echo "kill httpd..."
	killall httpd
	kill_process_with_term httpd 5000 httpd.conf
	kill_process_with_term httpd 80 httpd.conf
	echo "kill findhostd..."
	killall findhostd
	kill_process_with_term findhostd
	echo "Stop all ips..."
	dhcp_interfaces=`cat /proc/net/dev | grep eth | cut -d: -f 1`
	killall `basename ${dhcp_program:-/sbin/udhcpc}`
	if [ -x /sbin/udhcpc ]; then
		for dhcpif in ${dhcp_interfaces}
		do
			kill_dhcp_processes ${dhcpif}
			sleep 1;
			ifconfig ${dhcpif} 0.0.0.0 up
		done
	fi
	/sbin/route del default
	kill_process_with_term $CHECK_ROUTE_IN_PASSIVE
	kill_process_with_term synoaha monitor-route-all
	echo "Reset aha routing rule"
	/sbin/ip route | grep 169.254.0.0 | grep -v src | grep -v default | while read line; do /sbin/ip route del $line; done
	$EXEC_BINARY $BIN_SYNOAHA --net-status-changed
}

########### check-in control start ###########
restart_ha_mgr_daemon()
{
	kill_and_wait_process $exit_stop_process $AHA_MGR_DAEMON $AHA_COMM_DAEMON
	$EXEC_BINARY /bin/cp $TMP_AHA/$AHA_DAEMON_STATIC $BIN_AHA_DAEMON
	$EXEC_BINARY /bin/mv $TMP_AHA/$AHA_DAEMON_STATIC $BIN_AHA_DAEMON_STATIC
	$EXEC_BINARY /bin/ln -sf $BIN_AHA_DAEMON $BIN_AHA_MGR_DAEMON
	$EXEC_BINARY /bin/ln -sf $BIN_AHA_DAEMON $BIN_AHA_COMM_DAEMON

	$EXEC_BINARY $BIN_SYNOAHA --update-mgr-daemon-version
	$EXEC_BINARY $BIN_AHA_MGR_DAEMON $1 &
}
########### check-in control end ###########

Exit()
{
	if [ -n "$2" ]; then
		echo "Exit on error [$1] $2..."
	fi

	if [ $exit_become_active -eq $1 ]; then
		Ret=0
	else
		Ret=1
	fi

	# clear process and data
	necessary_daemon_stop $1
	$EXEC_BINARY $BIN_SYNOAHA --remove-all-AHA-msg-queues
	sync
	umount_fs
	unload_necessary_module $1
	network_stop

	rm -f $FLAGE_CHECK_STAGE

	if [ $exit_reboot -eq $1 ]; then
		umount /sys
		umount /proc
		# check if remote is online
		# if no, set expander HB longer to prevent fan from speeding up
		$EXEC_BINARY $BIN_SYNOAHA --reboot-prolong-expander-HB-timeout
		/sbin/reboot -f
		sleep 600
	elif [ $exit_poweroff -eq $1 ]; then
		umount /sys
		umount /proc
		/sbin/poweroff -f
		sleep 600
	fi

	rm -f $DUAL_GLIBC_PATH/tmp/aha/* &>/dev/null
	$EXEC_BINARY $BIN_SYNOAHA --clear-mgr-daemon-version

	exit $Ret
}

check_stage()
{
	touch $FLAGE_CHECK_STAGE
	local running_httpd=0
	# network start
	network_start

	SupportSAS=`/bin/get_key_value /etc.defaults/synoinfo.conf supportsas`
	if [ "$SupportSAS" = "yes" ]; then
		SASEnablePhy
	else
		Exit $exit_not_support_sas "This model is not supported sas"
	fi

	mount_fs

	# should be checked after mount_fs()
	if detect_manufactory_device; then
		touch $FLAGE_FIND_MANUFACTORY_DEVICE
		if [ "" == "`/usr/syno/bin/synodiskport -eunit 2>/dev/null`" ]; then
			touch /.nodisk
		fi
		Exit $exit_manufactory_dev_detected "Manufactory device detected."
	fi

	# load the necessary kernel modules
	load_necessary_module

	# Should be done before ha mgr run
	$EXEC_BINARY $BIN_SYNOAHA --init-mgr-daemon-version
	necessary_daemon_start $stage_check

	while [ 1 ]; do
		if [ -f "$GO_INTO_ACTIVE_MODE" ]; then
			/bin/rm -f $GO_INTO_ACTIVE_MODE
			Exit $exit_become_active "======= Now try to become active..."
		elif [ -f "$GO_INTO_JUNIOR_MODE" ]; then
			/bin/rm -f $GO_INTO_JUNIOR_MODE
			Exit $exit_go_into_junior_mode "======= Now go into junior mode"
		elif [ -f "$REBOOT" ]; then
			/bin/rm -f $REBOOT
			Exit $exit_reboot "======= Now reboot"
		elif [ -f "$POWEROFF" ]; then
			# Keep this file because network_stop() needs this information
			$EXEC_BINARY /usr/syno/bin/synoenc --poweroff_all
			Exit $exit_poweroff "======= Now poweroff"
		elif [ -f "$PASSIVE_ROLE_FOR_SCEMD" ]; then
			/bin/rm -f $PASSIVE_ROLE_FOR_SCEMD
			start_scemd
			$EXEC_BINARY $BIN_SYNOAHA --sync-time &
		elif [ -f "$PASSIVE_WEB_SERVER" ]; then
			/bin/rm -f $PASSIVE_WEB_SERVER
			if [ 0 == $running_httpd ]; then
				running_httpd=1
				{
					prepare_passive_web_server
				} &
			fi
		elif [ -f "$PASSIVE_WEB_SERVER_DISABLE" -a 1 == $running_httpd ]; then
			running_httpd=0
			{
				reset_passive_web_server
				/bin/rm -f $PASSIVE_WEB_SERVER_DISABLE
			} &
		elif [ -f "$RESTART_HA_MGR_DAEMON" ]; then
			restart_ha_mgr_daemon $stage_check
			/bin/rm -f $RESTART_HA_MGR_DAEMON
		fi
		sleep $TIME_TO_CHECK_IF_GO_INTO_NEXT_STAGE
	done


	Exit $exit_unknown_err "Unknown error"
}

junior_stage()
{
	mount_fs
	# Should be done before ha mgr run
	$EXEC_BINARY $BIN_SYNOAHA --init-mgr-daemon-version
	necessary_daemon_start $stage_junior
}

junior_monitor_reboot_or_poweroff()
{
	while [ 1 ]; do
		if [ -f "$REBOOT" ]; then
			necessary_daemon_stop $exit_reboot
			sync
			umount_fs
			echo "============ AHA: now reboot ============" > /dev/console
			/bin/rm -f $REBOOT
			# check if remote is online
			# if no, set expander HB longer to prevent fan from speeding up
			$EXEC_BINARY $BIN_SYNOAHA --reboot-prolong-expander-HB-timeout
			/sbin/reboot
			sleep 600
		elif [ -f "$POWEROFF" ]; then
			$EXEC_BINARY /usr/syno/bin/synoenc --poweroff_all
			necessary_daemon_stop $exit_poweroff
			sync
			umount_fs
			echo "============ AHA: now poweroff ============" > /dev/console
			/bin/rm -f $POWEROFF
			/sbin/poweroff
			sleep 600
		elif [ -f "$RESTART_HA_MGR_DAEMON" ]; then
			restart_ha_mgr_daemon $stage_junior
			/bin/rm -f $RESTART_HA_MGR_DAEMON
		fi
		sleep 2
	done
}

stage_change_start()
{
	echo "======== AHA: stage change start ========"
	mount_fs
	SYNOLoadModules sg
	$EXEC_BINARY $BIN_SYNOAHA --set_expander_HB &
}

stage_change_end()
{
	echo "======== AHA: stage change end ========"
	killall synoaha
	$EXEC_BINARY $BIN_SYNOAHA --set_all_expander_HB_timer 300
	SYNOUnloadModules sg
	umount_fs
}

action=$1;
shift

case "$action" in
	check_stage)
		check_stage
		;;
	junior_stage)
		junior_stage
		;;
	junior_monitor_reboot_or_poweroff)
		junior_monitor_reboot_or_poweroff
		;;
	stage_change_start)
		stage_change_start
		;;
	stage_change_end)
		stage_change_end
		;;
	load_network_modules_junior)
		network_start_junior
		;;
	*)
		echo "usage: {check_stage|junior_stage|junior_monitor_reboot_or_poweroff|stage_change_start|stage_change_end}"
		Exit $exit_unknown_err "Unknown error"
		;;
esac
