#!/bin/sh
#
# Copyright 2012-2013 VMware, Inc. All rights reserved.
#
# NSX-Management-Plane-Agent:
#   Start/Stop the NSX Management Place Agent
#
# Tell chkconfig to start us with starting rank 98 and shutdown rank 2.
# chkconfig: 2345 98 2
# description: NSX Management Place Agent
#

# variables
export PATH=/bin:/sbin:/usr/bin

MPA=/opt/vmware/nsx-mpa/bin/mpa
MPA_USR=mpa
MPA_SHELL=/bin/bash
MPA_TAG=NSX-Management-Plane-Agent
MPA_MAX_QUICK_RESTARTS="10"
MPA_MAX_RESTARTS="1000"
WATCHDOG_ARGS="-d -s ${MPA_TAG} -q ${MPA_MAX_QUICK_RESTARTS} -t ${MPA_MAX_RESTARTS}"

MPA_GROUP="host/vim/vmvisor/mpa"
MPA_SCHED_PARAMS=""
MPA_RPCMD="localcli --plugin-dir=/usr/lib/vmware/esxcli/int sched group"
MPA_MEMSIZE=64
MPA_ARGS=${MPA_SCHED_PARAMS}

WATCHDOG=/opt/vmware/nsx-mpa/bin/watchdog.sh

INITD_FUNCTIONS_FILE="/etc/rc.d/init.d/functions"
INITD_FUNCTIONS_BOOL=false
# Include source function library if available
if [ -f "$INITD_FUNCTIONS_FILE" ]; then
   INITD_FUNCTIONS_BOOL=true
   . "$INITD_FUNCTIONS_FILE"
fi

INITD_SUSE_FUNCTIONS_FILE="/lib/lsb/init-functions"
# Include source function library if available
if [ -f "$INITD_SUSE_FUNCTIONS_FILE" ]; then
   INITD_FUNCTIONS_BOOL=true
   . "$INITD_SUSE_FUNCTIONS_FILE"
fi

mpa_log() {
   echo "${1}"
   logger -p daemon.info -t NSX "${1}"
}

destroy_rp() {
   local TIMEOUT=5
   while [ $((TIMEOUT--)) -gt 0 ]; do
       ${MPA_RPCMD} delete --group-path=$1 2> /dev/null
       if [ $? -eq 0 ]; then
          mpa_log "Resource pool '$1' released."
          break
       else
          mpa_log "Resource pool '$1' release failed. retrying.."
       fi
       sleep 1
   done

   return 0
}

create_rp() {
   ${MPA_RPCMD} add --group-name=mpa --parent-path=host/vim/vmvisor 2> /dev/null
   if [ $? -ne 0 ]; then
      mpa_log "Unable to add rp for mpa"
      return 1
   fi
   ${MPA_RPCMD} setmemconfig --group-path=${MPA_GROUP} --min=${MPA_MEMSIZE} --max=-1 --minlimit=${MPA_MEMSIZE} --units=mb 2> /dev/null
   if [ $? -ne 0 ]; then
      mpa_log "Unable to setmemconfig for mpa"
      destroy_rp ${MPA_GROUP}
      return 1
   fi
   ${MPA_RPCMD} setcpuconfig --max=-1 --group-path=${MPA_GROUP} --units=mhz 2> /dev/null

   if [ $? -ne 0 ]; then
      mpa_log "Unable to setcpuconfig for mpa"
      destroy_rp ${MPA_GROUP}
      return 1
   fi

   return 0
}

start() {

   #create_rp

   # start MPA with watchdog
   if [ -z "$(pidof -s "${MPA}")" ] ; then
      ulimit -n 1024
      ulimit -c unlimited
      ${WATCHDOG} ${WATCHDOG_ARGS} "su ${MPA_USR} -c "${MPA} ${MPA_ARGS}" -s ${MPA_SHELL}" >/dev/null 2>&1
      mpa_log "${MPA_TAG} started"
   else
      mpa_log "${MPA_TAG} already running"
   fi

}

stop() {
   if [ -n "$(pidof -s "${MPA}")" ] ; then
      # This only stops the watchdog process.
      ${WATCHDOG} -k "${MPA_TAG}"

      # Use killproc function if available
      if [ "$INITD_FUNCTIONS_BOOL" = true ]; then
         killproc "${MPA}" -KILL
         mpa_log "${MPA_TAG} Using killproc to terminate the process"
      fi

      # Repeat the kill if pid is still found
      local KILL_ATTEMPT=1
      while [ -n "$(pidof -s "${MPA}")" ] ; do
         pkill -KILL -f "${MPA}"
         mpa_log "${MPA_TAG} Terminating ${MPA} service. Attempt #$((KILL_ATTEMPT++))"
         if [ $((KILL_ATTEMPT)) -eq 10 ]; then
            mpa_log "${MPA_TAG} Unable to terminate ${MPA}"
            exit 1
         fi
         # Wait for the process to terminate
         sleep 1
      done

      if [ -z "$(pidof -s "${MPA}")" ] ; then
         mpa_log "${MPA_TAG} stopped"
      fi
   else
      mpa_log "${MPA_TAG} is not running"
   fi

   #destroy_rp ${MPA_GROUP}
}

#
# main
#
case "${1}" in
   "start")
      start
   ;;
   "stop")
      stop
   ;;
   "status")
      if [ -n "$(pidof -xs "${MPA}")" ] ; then
         echo "${MPA_TAG} is running"
         exit 0
      else
         echo "${MPA_TAG} is not running"
         # Returning 3 like everyone else.
         exit 3
      fi
   ;;
   "restart")
      stop
      sleep 1
      start
   ;;
   *)
      echo "Usage: $(basename ${0}) {start|stop|status|restart}"
      exit 1
   ;;
esac
