#!/bin/sh

supervisor_trap () {
  echo "gets trap on supervisor"
  rm -rf /tmp/check_coredump
}
trap 'supervisor_trap; exit 1' INT TERM ABRT QUIT ALRM

critical_processes="frpc|frpc"

all_installed=0
updated=0

check_critical_processes()
{
  for crit_proc in $critical_processes
  do
    OIFS=$IFS;IFS="|";set -- $crit_proc;crit_proc_name=$1;crit_initd_name=$2;IFS=$OIFS
    [ ! -e "/etc/init.d/${crit_initd_name}" ] && continue
    pids=$(pgrep "$crit_proc_name")
    count=$(echo "$pids" | awk 'END{print NR}')
    if [ -z "$pids" -o "$count" -gt 1 ]
    then
      echo "$crit_proc_name is abnormal, pids:${pids}, count:${count}" | logger -t "supervisor" -p 5
      /etc/init.d/${crit_initd_name} restart
    fi
  done
}

check_coredump()
{
  lock -n /tmp/check_coredump
  [ "$?" != "0" ] && return 1
  cd /tmp/
  rm -rf gcom.*.core
  for core_file in `ls *.core 2>/dev/null`
  do
    echo "Core file is abnormal:$core_file" | logger -t "supervisor" -p 5
    if [ `free | awk '/Mem/{print $4}'` -gt "20000" ]
    then
      tar czvf /app/${core_file}.tar.gz "$core_file" /etc/issue
    fi
    rm -rf "$core_file"
  done
  cd -
  lock -u /tmp/check_coredump
}

check_df()
{
  top_info="$1"
  df_info="$2"
  tmp_free=$(echo "$df_info" | awk '/\/tmp$/{print $4}')
  mem_free=$(cat /proc/meminfo | awk '/MemAvailable/{print $2}')
  flash_free=$(echo "$df_info" | awk '/\/overlay$/{print $4}')
  [ -z "$flash_free" ] && flash_free=$(echo "$df_info" | awk '/\/$/{print $4}')
  echo "tmp_free":$tmp_free "flash_free:"$flash_free "mem_free:"$mem_free | logger -t "supervisor" 
  if [ "$mem_free" -lt "1024" ]
  then
    echo 3 > /proc/sys/vm/drop_caches
    mem_free=$(cat /proc/meminfo | awk '/MemAvailable/{print $2}')
    if [ "$mem_free" -lt "1024" ]
    then
      echo "$top_info" > /app/top_info
      echo "$(cat /proc/meminfo)" > /app/meminfo
      echo "reboot as less sys resource" | logger -t "supervisor" -p 3
      echo "reboot as less sys resource" > /dev/console
      sleep 10
      reboot -f
    fi
  fi
  if [ "$flash_free" -lt "2048" ]
  then
    echo "du /app" > /app/du_info
    rm -rf /app/*.log /app/*.tar.gz
    /usr/bin/sqlite3 /app/collect.db "delete from data_table where report=1;"
    /usr/bin/sqlite3 /app/MQTT_REPORT_0.db "delete from data_table where report=1;"
    /usr/bin/sqlite3 /app/MQTT_REPORT_1.db "delete from data_table where report=1;"
    /usr/bin/sqlite3 /app/MQTT_REPORT_2.db "delete from data_table where report=1;"
    /usr/bin/sqlite3 /app/MQTT_REPORT_3.db "delete from data_table where report=1;"
    /usr/bin/sqlite3 /app/MQTT_REPORT_4.db "delete from data_table where report=1;"
  fi
  if [ "$tmp_free" -lt "2048" ]
  then
    echo "$df_info" > /app/df_info
    echo "reboot as less sys resource" | logger -t "supervisor" -p 3
    echo "reboot as less sys resource" > /dev/console
    sleep 10
    reboot -f
  fi
}

check_sysstat()
{
  top_info=$(top -n1 -b)
  echo "$top_info"| logger -t "supervisor"
  df_info=$(df)
  echo "$df_info" | logger -t "supervisor"
  check_df "$top_info" "$df_info"
}

check_installed_ipk()
{

  if [[ "$all_installed" == "1" ]]
  then
    echo "All IPK Installed" | logger -t "IPK CHECK" -p 3
    return
  fi

  local flag=0
  if [ -f "/app/config/ipk_installed" ]; then
    for line in `cat /app/config/ipk_installed | awk '{print $1}'`
    do
      result=$(/bin/opkg list-installed | grep "^$line ")
      if [[ "$result" == "" ]]
      then
        flag=1
        echo "$line not installed" | logger -t "IPK CHECK" -p 3
        [ "$updated" == 0 ] && {
            /bin/opkg update
            updated=1
        }
        str=`cat /app/config/ipk_installed`
        args=${str#"$line "}
        /bin/opkg $args
      fi
    done
  fi
  if [ "$flag" -eq "0" ]; then
    all_installed=1
    echo "all installed" | logger -t "IPK CHECK" -p 3
  fi
}

while :
do
  sleep 60
  check_critical_processes &
  check_sysstat &
  check_coredump &
  check_installed_ipk &
done
