#!/bin/bash  
#
# © Copyright IBM Corp. 2008.  All Rights Reserved.
# Author: Keith Mannthey <kmannth@us.ibm.com>
#
# ibm-prtm	This shell script takes care of starting and stopping
#		ibm-prtmd (IBM Premium Real-Time Mode daemon).
#
### BEGIN INIT INFO
# Provides: ibm-prtmd
# Required-Start:
# Required-Stop:
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Description: Start the IBM Premium Real-Time daemon
### END INIT INFO

# description: Enters/Exits IBM Premium Real-Time Mode. \
# Enables and Disables IBM Premium Real-Time Mode, as well as starts and \
# stops the ibm-prtmd daemon.

# Source function library.
. /etc/rc.status

RETVAL=0
prog="ibm-prtmd"
PIDFILE=/var/run/ibm-prtmd.pid
NAME="IBM Real-Time HW Daemon"
get_pid() {
	local pidfile="$1"
	PID=`cat $pidfile 2>/dev/null`
	if [ $? -eq 0 ] && grep -q ibm-prtmd /proc/$PID/cmdline 2>&1 /dev/null; then
		echo $PID
		return 0
	fi
	return 1
}
start() {
	PID=`get_pid $PIDFILE`
	if [ $? -eq 0 ]; then
		echo "ibm-prtmd already running (pid $PID)"
		exit 1
	fi

	if ! modprobe ibm_rtl >/dev/null 2>&1
	then 
		logger -s -t "$NAME" "BIOS Real-Time Mode not supported on this hardware or kernel."
		exit 1
	fi

	logger -s -t "$NAME" "BIOS Real-Time module loaded."

	#k8_edac gets in the way on some machines; remove it and use amd64_edac
	if [ `lsmod | grep -c k8_edac ` -ne 0 ]; then
		rmmod k8_edac && modprobe amd64_edac
		if [ "$?" -ne "0" ]; then
			logger -s -t "$NAME" "Please install amd64_edac module!"
			exit 1;
		fi
	fi

	for mod in ipmi_si ipmi_msghandler ipmi_devintf 
	do
		modprobe $mod
		if [ "$?" -ne "0" ]; then
			logger -s -t "$NAME" "Please install $mod module!"
			exit 1;
		fi
	done 
	
	#ipmi initialization takes a little while; wait
	while [ ! -e /dev/ipmi0 ]; do sleep 0.1; done
	
	if ! which ipmitool >/dev/null 2>&1; then 
		logger -s -t "$NAME" "Please install ipmitool!"
		exit 1;
	fi

	if ! echo 1 > /sys/devices/system/ibm_rtl/state; then
		logger -s -t "$NAME" "BIOS unable to enter Real-Time Mode."
		logger -s -t "$NAME" "You may have a system configuration issue."
		
		exit 1
	fi

	# Ask the BMC to stop generating SMIs; request then check result 
	ipmitool raw 0x3A 0x1A 0 >/dev/null 2>&1
	if [ "$(ipmitool raw 0x3A 0x1A)" != " 00" ]; then
		logger -s -t "$NAME" "BMC unable to enter Real-Time Mode."
		logger -s -t "$NAME" "Power capping, acoustical mode and some power configurations"
		logger -s -t "$NAME" "may not be supported.  Please check your system"
		logger -s -t "$NAME" "configuration for proper setup."
		echo 0 > /sys/devices/system/ibm_rtl/state
		exit 1
	fi
		

	# Start daemons.
	echo -n "Starting $prog: "
	/usr/sbin/$prog
	RETVAL=$?
	if [ $RETVAL -ne 0 ]; then
		logger -s -t "$NAME" "An error has occurred!"
		logger -s -t "$NAME" "Your system may experience System Management Interrupts."
		logger -s -t "$NAME" "Please check your system configuration."
		#$prog failed to start undo state 
		echo 0 > /sys/devices/system/ibm_rtl/state
		ipmitool raw 0x3A 0x1A 1
		rm -f /var/lock/subsys/$prog
	else
		logger -s -t "$NAME" "System Management Interrupts have been disabled to"
		logger -s -t "$NAME" "allow this system to run in Real-Time Mode."
		touch /var/lock/subsys/$prog
	fi 
	
	return $RETVAL
}

stop() {
	echo 0 > /sys/devices/system/ibm_rtl/state
	ipmitool raw 0x3A 0x1A 1
	logger -s -t "$NAME" "Thermal policies (ie. acoustic mode) which were enabled on"
	logger -s -t "$NAME" "systems running in Real-Time Mode may not be accepted."
	logger -s -t "$NAME" "Please set thermal policies on this system again if desired."
	PID=`get_pid $PIDFILE`
	if [ $? -eq 0 ]; then
		kill -9 $PID
		true
	else
		echo "ibm-prtmd is not running"
		false
	fi
	RETVAL=$?
	rm -f $PIDFILE
	echo
	[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog
	return $RETVAL
}

# See how we were called.
case "$1" in
  start)
	start
	rc_status -v
	;;
  stop)
	stop
	rc_status -v
	;;
  status)
	PID=`get_pid $PIDFILE`
	if [ $? -eq 0 ]; then
		echo "ibm-prtmd running... (pid $PID)"
	else
		echo "ibm-prtmd is not running"
		rm -f $PIDFILE
	fi
	;;
  restart|reload)
	stop
	rc_status -v
	start
	rc_status -v
	RETVAL=$?
	;;
  condrestart)
	if [ -f /var/lock/subsys/$prog ]; then
		stop
		start
		RETVAL=$?
	fi
	;;
  *)
	echo $"Usage: $0 {start|stop|restart|condrestart|status}"
	exit 1
esac

exit $RETVAL
