#!/bin/sh
# $Copyright$     NB: This is an auto-generated comment with copyright note below. DO NOT MODIFY OR REMOVE!
# Copyright 2009-2018 FUJITSU LIMITED
# All rights reserved
#

#
# srvmagt:	ServerView Agent Linux SNMP subagent Daemons connect to the
#           snmpd daemon and provide information about the system
#
# chkconfig: 2345 59 02
# processname: sc2agt
# processname: thragt
# processname: busagt
# processname: hdagt
# processname: unixagt
# processname: etheragt
# processname: securagt
# processname: statusagt
# processname: invagt
# processname: vvagt
# processname: hpsimagt
# processname: vmeagt
# processname: svupdateagt
# processname: osagt
# processname: vmeagt
# description: Starts and stops the ServerView Agent Linux SNMP subagent Daemons
#
### BEGIN INIT INFO
# Provides: srvmagt
# Required-Start: $local_fs $network $syslog snmp eecd
# Required-Stop:
# Default-Start: 2 3 5
# Default-Stop: 0 1 6
# Description: Starts and stops the ServerView Agent Linux SNMP subagent Daemons
### END INIT INFO
#

#
# Exit status codes (see LSB 3 spec, ch. 20) are :
# 0     OK
# 1     generic or unspecified error
# 2     invalid or excess argument(s)
# 3     unimplemented feature (e.g. "reload")
# 4     user had insufficient privileges
# 5     program is not installed
# 6     program is not configured
# 7     program is not running
# 8+    reserved (see LSB Core Spec 3.1, ch. 20)

# Set up a decent path.

PATH="/sbin:/usr/sbin:/bin:/usr/bin"
export PATH

# Messages when exchanging the native snmpd with the ServerView instance

SVSnmpMsg="SNMP Daemon snmpd restarted. Changed from %s snmpd version %s to %s snmpd version %s"
SVSnmpd="ServerView"
NativeSnmpd="native"

# Use LSB function library for convenience.

[ -f /lib/lsb/init-functions ] && . /lib/lsb/init-functions

# Source ServerView function library

. /etc/srvmagt/functions

myname="$0"
mode="$1"

# skip first param
shift

. /etc/srvmagt/config
# get the names of the agents (without their "agt" suffix) from the config file (Default: all)
AllAgent="sc2 bus hd unix ether bios secur status inv thr vv hpsim svupdate os vme vmesnmp"
agentlist=${AgentsToBeStarted:=$AllAgent}

[ $# -ge 1 ] && agentlist="$*"

Unknown="unknown"
SELinux="$Unknown"
[ -f /etc/selinux/config ] && {
	type -f getenforce >/dev/null 2>&1
	if [ $? -eq 0 ]; then
		SELinux=$(getenforce)
	else
		SELinux=$(grep '^[[:space:]]*SELINUX=' /etc/selinux/config) || SELinux="$Unknown"
		SELinux=${SELinux##*=}
		SELinux=${SELinux%% *}
	fi
}

[ "$mode" = stop ] &&  {
	(
		flock -n  500
		if [ $? -eq 1 ]; then
			mylog_failure_msg "Service locked. Try $myname $mode later on"
			exit 1
		fi

		# Stop each running subagent daemon. This SHOULD use LSB killproc.

		# Turn off periodical supervision of srvmagt daemons
		rm -f /etc/srvmagt/srvmagtCronOn
		logger -t $MYNAME "Periodical supervision turned off."

		# remove udev rules and lib file, if existing
		if [ -e /etc/udev/rules.d/srvmagt.rules ]; then
			/bin/rm -f /etc/udev/rules.d/srvmagt.rules
			/bin/rm -f /lib/udev/srvmagt_udev_hotplug.sh
			if [ -e /sbin/udevadm ]; then
				/sbin/udevadm control --reload-rules  >/dev/null 2>&1
			fi
		fi	

		running=0
		errors=0
		for agt in $AllAgent; do
			inList=0
			echo $agentlist | grep -qw $agt && inList=1
			pid=$(mypidof "/usr/sbin/${agt}agt") || {
				[ $inList -eq 1 ]  && 
						mylog_success_msg "Shutting down ServerView ${agt}agt (stopped)"
				continue
			}
			let running++

			[ $# -ge 1 -a $inList -eq 0 ] && continue
			# this is a hack for the time being
			if [ "${agt}" = "vme" ]; then
				killproc "vmeagt"
			else
				killproc "/usr/sbin/${agt}agt"
			fi
			success=$?

			if [ $success -eq 0 ]; then
				mylog_success_msg "Shutting down ServerView ${agt}agt"
			else
				mylog_failure_msg "Shutting down ServerView ${agt}agt"
				let errors++
			fi
		done

		[ ${SELinux:1:7} = "isabled" -o "$SELinux" = "$Unknown" ] || {
			# Removing SELinux policy module vme.pp for RHEL6
			module=`semodule -l 2>/dev/null| grep "vme" | wc -l`
			if [ $module -ne 0 ]; then
				semodule -r vme
				restorecon -F /etc/srvmagt/VME/bin/vmeagt
			fi
			}

		[ -e /var/lock/subsys/srvmagt ] &&  rm -f /var/lock/subsys/srvmagt

		[ $running -eq 0 ] && {
			flock -u 500
			exit 0
		}
		[ $errors -eq 0 ] && {
			flock -u 500
			exit 0
		}

		flock -u 500
		exit 1 
	) 500>/var/log/srvmagt/lock.srvmagt-etc

	SubshellStatus=$?
	exit $SubshellStatus
}

# perform SetSvEnv only if not yet done
[ -z "$SV_NICKNAME" ] && SetSvEnv

# This path is needed to catch additional OEM libs for vmeagt
#if [ "$SV_ARCH" != "x86_64" -o "${SV_NICKNAME:0:4}" = "SLES" -o "${SV_NICKNAME:0:4}" = "RHEL" -a "$SV_NICKNAME" != "RHEL7" ]; then
if [ "$SV_ARCH" = "x86_64" -a "$SV_NICKNAME" != "RHEL5" -a "$SV_NICKNAME" != "OVM32" ]; then
	LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/etc/srvmagt/VME/lib64
else
	LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/etc/srvmagt/VME/lib
fi


# Source my configuration file value and use them as default values
# unless there is already a value in the environment

UserGroup=${UserGroup:-bin}
NoAccountCheck=${NoAccountCheck:-0}
ShutdownDelay=${ShutdownDelay:-0}
UseServerViewSnmpd=${UseServerViewSnmpd:-0}

exportConfVars

# makeXpairsfromMSB - transform each 16-bit MSB numbers into 2 hexdigit pairs in LSB
#
# $@        each argument is a 16-bit MSB numbers (for example 0123)
# stdout	Present the arguments as space-separated hexdigit pairs,
#           two adjacent pairs present the MSB number in LSB (for example 23 01)

function makeXpairsfromMSB() {
	local s=""

	[ "$#" -gt 0 ] || return
	while [ $# -gt 0 ] ; do
		s="$s ${1:2:2} ${1:0:2}"
		shift
	done
	printf "${s#* }"	# remove the leading space
}

# TurnOnCron - turn on periodical supervision of srvmagt daemons
# 	The root's crontab file contains the script srvmagtCron inserted during
# 	the daemons start that periodical executes the checking script.
#	The file "srvmagtCronOn" in /etc/srvmagt is created at the 'turn on'.
# 	If the file does not exist, then srvmagtCron will terminate doing nothing.


function TurnOnCron(){

# create temporary files with randomized name
TmpRoot=$(mktemp) || return
Err=$(mktemp) || return
	crontab -l -u root >$TmpRoot 2>$Err 
	if [ $? -ne 0 ]; then
		fgrep "no crontab" $Err >/dev/null ||
		{
			logger -t $MYNAME "Error: Periodical supervision not available."
			rm -f $TmpRoot $Err
			return
		}
	fi
	
	fgrep "srvmagtCron"  $TmpRoot>/dev/null
	if [ $? -eq 0 ]; then   
		grep "0,5,10,15,20,25,30,35,40,45,50,55.*srvmagtCron.*" $TmpRoot>/dev/null && {
		#  old crontab entry found, modify it
			sed -i '/srvmagtCron.$/s/0,5,10,15,20,25,30,35,40,45,50,55/0,15,30,45/' $TmpRoot
			/usr/bin/crontab -u root $TmpRoot >/dev/null 2>&1
		}
	else
		echo "# srvmagtCron: restarts daemons that died" >> $TmpRoot
		echo "0,15,30,45 * * * * /bin/sh -c \"[ -x /etc/srvmagt/srvmagtCron ] && /etc/srvmagt/srvmagtCron\"" >> $TmpRoot
		/usr/bin/crontab -u root $TmpRoot >/dev/null 2>&1
	fi
	rm -f $TmpRoot $Err

	echo "" > /etc/srvmagt/srvmagtCronOn
	logger -t $MYNAME "Periodical supervision turned on."
}


# For SLES9 SP3, it is necessary to have SNMPCONFPATH="/etc" in the
# environment of each subagent so that the SNMP configuration file
# handler finds "/etc/snmpd.conf" to fetch to community.
# This is not necessary for SLES10, RHEL4 and RHEL5.

[ -f /etc/snmpd.conf ] && export SNMPCONFPATH="/etc"

# Be restictive with access right while creating files
umask 0066

if [ "$mode" = "trace" ]
then
        flags="-d -l"
        export TraceFileLimit=0
        export SV_LOG_DEBUG_LEVEL=255
elif [ "$mode" = "start" ]
then
        flags=-d
        [ "$TraceFileLimit" = "0" ] && {
            flags=
            export SV_LOG_DEBUG_LEVEL=0
        }
fi

case "$mode" in
trace|start)

	(
		flock -n  500
		if [ $? -eq 1 ]; then
			mylog_failure_msg "Service locked. Try $myname $mode later on"
			exit 1
		fi

		# Save existing ServerView Agent Linux logfiles

		( cd /var/log/srvmagt
		logFiles=$(find . -name log.\*agt\*)
		[ -f vme_status.xml ] &&
			logFiles="${logFiles} vme_status.xml"
		[ -z "$logFiles" ] || tar -czf log.AgentLogs.tgz $logFiles)

		# Do not run wait cycles and checks, if all requested subagents are already running

		count=0
		for agt in $agentlist; do
			pid=$(mypidof "/usr/sbin/${agt}agt") && {
				mylog_success_msg "Starting ServerView ${agt}agt $flags (already running $pid)"
				continue
			}
			let count++
		done
		[ $count -eq 0 ] && {
			flock -u 500
			exit 0
		}

		# Without snmpd, SNMP operation is impossible for ALL subagent

		pid=$(mypidof "/usr/sbin/snmpd") || {
			mylog_failure_msg "Starting ServerView agents: service snmpd is not running!"
			flock -u 500
			exit 1
		}

		# Without the service eecd HW monitoring for SOME subagents is impossible.
		# Wait until eecd sockets are ready. Then give eecd another grace period
		# to complete init. All this to avoid SNMP timeouts that might stress snmpd.

		pid=$(mypidof "/usr/sbin/eecd") || {
			mylog_failure_msg "Starting ServerView agents: service eecd is not running!"
			flock -u 500
			exit 1
		}

		count=${WaitForEecdSockets:=300}    # If <100 adjust \b's below
		echo -e "Waiting for eecd sockets ...\c"
		while [ $count -gt 0 ]; do
			[ -S /dev/eecda -a -S /dev/eecds ] && break
			sleep 1
			count=$(($count - 1))
			if [ $count -ge 100 ]; then
				echo -e "\b\b\b$count\c"
			elif [ $count -ge 10 ]; then
				echo -e "\b\b\b $count\c"
			else
				echo -e "\b\b\b  $count\c"
			fi
		done

		[ $count -eq 0 ] && {
			echo " giving up after $WaitForEecdSockets seconds!"
			mylog_failure_msg "Starting ServerView agents: eecd sockets do not exist!"
			flock -u 500
			exit 1
		}
		echo -e "\b\b\bdone ($count)"

		#[ "$#" -eq 0 ] && wait4eecd     # Only if ALL agents are started (during reboot)

		# Enable the configured UserGroup to issue eecdcp commands (besides root)

		chgrp $UserGroup /dev/eecd*[asj] && chmod g+w /dev/eecd*[asj] && {
		logger -t $MYNAME "Starting ServerView agents: eecd sockets enabled for group $UserGroup"
		}

		# Set the ShutdownDelay value into the config space

		eecdcp -c oc=e002 oe=1700 $(makeXpairsfromMSB $(printf "%04x" $ShutdownDelay)) >/dev/null

		[ $SV_NICKNAME = "RHEL6" -o $SV_NICKNAME = "RHEL7" ] && {
			[ ${SELinux:1:7} = "isabled" -o "$SELinux" = "$Unknown" ] || {
				# Adding SELinux policy module vme.pp for RHEL6
				module=`semodule -l 2>/dev/null | grep "vme" | wc -l`
				if [ $module -eq 0 ]; then
					restorecon -F /etc/srvmagt/VME/bin/vmeagt
					semodule -i   /etc/srvmagt/VME/bin/vme.pp
					restorecon -F /etc/srvmagt/VME/bin/vmeagt
					module=`semodule -l 2>/dev/null | grep "vme" | wc -l`
					if [ $module -eq 0 ]; then
						mylog_failure_msg "failed to add selinux module vme.pp"
					fi
				fi
			}
		}

		if [ "$SV_ARCH" = "x86_64" ]; then
			# Disable glibc internal allocator checks.
			# This is very ugly hack, but this allows daemons to start
			export MALLOC_CHECK_=0
		fi
		# Now start the requested not yet running subagents
		# Return OK and set subsystem ready if ALL subagents started.

		errors=0
		for agt in $agentlist; do
		pid=$(mypidof "/usr/sbin/${agt}agt") && continue

		[ "$agt" = "vv" ] && testVersionViewFile
		[ "$agt" = "secur" ] && writeAuthConf
		[ "$agt" = "sc2" ] && MibSetEnabled && MibSetAgentShutEnabled
		[ "$agt" = "vme" ] && flags="-d -p /etc/srvmagt/VME" && export LD_LIBRARY_PATH

		# Start the daemon. This SHOULD use the LSB start_daemon routine.

		[ "$SV_DAEMON_COREFILE_LIMIT" = "" -o "$SV_DAEMON_COREFILE_LIMIT" = 0 ] ||
		ulimit -c $SV_DAEMON_COREFILE_LIMIT

		rm -f /var/log/log.${agt}agt /var/log/log.${agt}agt_[ab]
		rm -f /var/log/srvmagt/log.${agt}agt /var/log/srvmagt/log.${agt}agt_[ab]

		/usr/sbin/${agt}agt $flags >/var/log/srvmagt/log.${agt}agt 2>&1 </dev/null

		# Show formatted completion status

		if [ $? -eq 0 ]; then
		    mylog_success_msg "Starting ServerView ${agt}agt $flags"
		else
		    mylog_failure_msg "Starting ServerView ${agt}agt $flags"
		    let errors++
		fi
		done

		if [ $errors -eq 0 ]; then
			[ -d /var/lock/subsys ] &&  touch /var/lock/subsys/srvmagt
			# Turn on periodical supervision of srvmagt daemons
			TurnOnCron

			# ON ESX4, if the appliance svappliance exists, write name, working directory
			# and timeout of shutdown routine into config space 
			[ $SV_NICKNAME = "ESX4" ] &&
			vmware-cmd -l|fgrep -i svappliance >/dev/null && {
				eecdcp -c oc=e002 oe=1710 \"ChkStatusOnShutdown\" >/dev/null
				eecdcp -c oc=e002 oe=1711 \"/etc/srvmagt\" >/dev/null
				eecdcp -c oc=e002 oe=1712 B4 >/dev/null
			}

			# create udev rules and lib file, if necessary
			if [ -e /sbin/udevd ]; then
				# install udev rules and lib file only on PRIMEQUEST system
				/usr/sbin/dmidecode | fgrep PRIMEQUEST >/dev/null 2>&1 
				if [ $? -eq 0 ]; then
					/bin/cp -p -f /etc/srvmagt/srvmagt_udev_hotplug.sh /lib/udev/srvmagt_udev_hotplug.sh
					/bin/cp -p -f /etc/srvmagt/srvmagt.rules	   /etc/udev/rules.d/srvmagt.rules
					if [ -e /sbin/udevadm ]; then
						/sbin/udevadm control --reload-rules  >/dev/null 2>&1
					fi
				fi
			fi

			flock -u 500
			exit 0
		else
			[ -e /var/lock/subsys/srvmagt ] &&  rm -f /var/lock/subsys/srvmagt
			flock -u 500
			exit 1
		fi
	) 500>/var/log/srvmagt/lock.srvmagt-etc

	SubshellStatus=$?
	exit $SubshellStatus ;;

archive)
	# Run snmpwalk on all oids in StartOIds.ini
	# Output stored under directory : /var/log/srvmagt/ARCHIVE
	/etc/srvmagt/archive
	exit $? ;;

force-reload)
	# Reload configuration, if the service supports this,
	# otherwise start the service if it is not running

	$0 start
	exit $? ;;

restart)

	$0 stop  $*
	$0 start $*
	exit $? ;;

status)
	# Status codes in this case are:
	# 0     all agents are running [OK]
	# 1     service is dead /var/run/<pid file> exists
	# 2     service is dead and /var/lock/<lock file> ecists
	# 3     one or more agents are not running
	# 4     service status is unknown
	# 5+    reserved (see LSB Core Spec 3.1, ch. 20)

	notRunning=0
	for agt in $AllAgent; do
	inList=0
	echo $agentlist | grep -qw $agt && inList=1
	[ $# -ge 1 -a $inList -eq 0 ] && continue
		pid=$(mypidof "/usr/sbin/${agt}agt")
		if [ $? -eq 0 ]; then
			if [ $inList -eq 1 ]; then
				statMsg=$(printf "Checking for ServerView %s: pid %s, %s" ${agt}agt $pid $(mapAgtState $agt))
			else
				statMsg=$(printf "ServerView %s not in list but %s, pid %s" ${agt}agt $(mapAgtState $agt) $pid)
			fi
		else
			[ $inList -eq 0 ]  &&  continue
			let notRunning++
			statMsg=$(printf "Checking for ServerView %s: stopped" ${agt}agt)
		fi
		echo $statMsg
		logger -t $MYNAME $statMsg
	done

	[ $notRunning -eq 0 ] && exit 0
	exit 3 ;;

try-restart|reload|*)
	echo "Usage: $0 {start|trace|stop|restart|archive|force-reload|status} [<agent> ...]"
	exit 1 ;;
esac

exit 1
# EOF
