#!/bin/sh

# NOTICE_START
# Licensed Materials - Property of IBM
# "Restricted Materials of IBM" -- 5746-SM2
# (C) Copyright IBM Corp. 2007, 2009 All Rights Reserved.
# US Government Users Restricted Rights - Use, duplication or disclosure
# restricted by GSA ADP Schedule Contract with IBM Corp.
# NOTICE_END

### BEGIN INIT INFO
# Provides: powervm-lx86-rccommon
# Default-Start: $null
# Default-Stop:  $null
# Required-Start:
# Required-Stop:
# Short-Description: powervm-lx86-rccommon
# Description: powervm-lx86-rccommon. This script is used to propagate runlevel changes from the host system to the x86 World.
### END INIT INFO

# This script is used to propagate runlevel changes from the host
# system to the x86 World

# source functions library
if [ -f /lib/lsb/init-functions ]; then
  . /lib/lsb/init-functions
elif [ -f /etc/init.d/functions ]; then
  # RedHat compatibility
  . /etc/init.d/functions
  log_success_msg () {
    echo -n $*
    success "$*"
    echo
  }
  log_failure_msg () {
    echo -n $*
    failure "$*"
    echo
  }
  alias log_failure_msg=failure
else 
  echo "[$0][Error: 0005] Unable to source init-script functions." > /dev/stderr
  exit 1
fi

SCRIPT_NAME=$0
PACKAGENAME=powervm-lx86

# Return values
# 0 - success
# 1 - misc error
# 2 - invalid or excess args
# 3 - unimplemented feature (e.g. reload)
# 4 - insufficient privilege
# 5 - program not installed
# 6 - program not configured

function load_or_default 
{
  local KEY="$1"
  local DEFAULT="$2"

  local VALUE="$DEFAULT"
  if [ -s /etc/opt/$PACKAGENAME/config ]
  then
    LINE="$(grep "^$KEY\=" /etc/opt/$PACKAGENAME/config)"
    if [ $? -eq 0 ]
    then
      CUT=$(echo "$LINE" | cut -d '=' -f 2 | tail -n 1)
      if [ $? -eq 0 ]
      then
        VALUE="$CUT"
      fi
    fi
  fi
  echo "$VALUE"
}


if [ -z "$POWERVM_LX86_EXEDIR" ] ;
then
  POWERVM_LX86DIR=$(load_or_default POWERVM_LX86_LOCATION /opt/$PACKAGENAME)"/bin"
else
  POWERVM_LX86DIR="$POWERVM_LX86_EXEDIR"
fi

if [ -z "$POWERVM_LX86_X86WORLD" ] ;
then
    POWERVM_LX86_PATH=$(load_or_default SUBJECT_WORLD_ROOT "/i386")
else
    POWERVM_LX86_PATH=$POWERVM_LX86_X86WORLD
fi

# Check that this is lower case, we need to match 'y' or 'Y'
SELINUX_TRANS_ENABLED=$(tr '[:upper:]' '[:lower:]' <<< $(load_or_default ENABLE_SELINUX_TRANSITIONS n))

POWERVM_LX86_DAEMON_DIR=/var/opt/$PACKAGENAME/daemon

# If we're using SELinux, runx86 can do the context transitioning for us
RUNX86="/usr/local/bin/runx86"

# If the rest of the package has been removed, but the init script remains, exit with error 5
# (as per LSB specification 1.3)
test -x "$POWERVM_LX86DIR/$PACKAGENAME" ||
{
  if [ "$1" = "stop" ]; then
    exit 0;
  else
    echo "$POWERVM_LX86DIR/$PACKAGENAME is not installed";
    exit 5;
  fi
}

test -x "$POWERVM_LX86DIR/$PACKAGENAME-daemon" ||
{
  if [ "$1" = "stop" ]; then
    exit 0;
  else
    echo "$POWERVM_LX86DIR/$PACKAGENAME-daemon is not installed";
    exit 5;
  fi
}

check_privileges()
{
    if [ ! $EUID -eq 0 ]
    then
        echo "[$0][Error: 0001] You must be root to run this script."
        exit 4
    fi
    if [ -e "/etc/opt/$PACKAGENAME/config" ]
 	  then
 	    if [ "`stat -c%U /etc/opt/$PACKAGENAME/config 2>/dev/null`" != "root" ]
      then
 	       echo "[$0][Error: 0002] /etc/opt/$PACKAGENAME/config must be owned by root."
 	       exit 1
 	    fi
            # permissions in -rwxrwxrwx format
            CONF_PERM=`stat -c%A /etc/opt/$PACKAGENAME/config 2>/dev/null`
            # is the w permission contained in the last two sets of permissions?
            echo ${CONF_PERM#????} | grep w &>/dev/null
 	    if [ $? -eq "0" ]
 	    then
 	      echo "[$0][Error: 0003] /etc/opt/$PACKAGENAME/config must be writable only by root."
 	      exit 1
 	    fi
 	  fi  
}

run_subject_rc()
{
  pgrep -x -f "$POWERVM_LX86DIR/$PACKAGENAME-daemon" &>/dev/null
  if [ "$?" -ne 0 ] ; then
    # daemon not running, we need to clean translator processes
    for THEPID in `pgrep -x $PACKAGENAME 2>/dev/null`
    do
      # making sure the pid corresponds to a $PACKAGENAME process
      # Notice the extra space  
      THEFILENAME="`readlink /proc/$THEPID/exe` "
      # using grep instead of direct comparison to cover cases
      # when the binary has been deleted (deleted appended to /proc/$THEPID/exe)
      # and possibly other cases as well
      # Notice the extra space  
      echo "$THEFILENAME" | grep "$POWERVM_LX86DIR/$PACKAGENAME " &>/dev/null  
      if [ $? -eq "0" ]
      then
        LX86_PROCS="$LX86_PROCS $THEPID"
      fi
    done

    if [ ! -z "$LX86_PROCS" ] ;
    then
      # sending TERM signal to any processes left
      echo "Sending TERM signal to rest of $PACKAGENAME processes"
      kill -TERM $LX86_PROCS 2>/dev/null
      # sleep for a few secs to give processes time to finish
      sleep 4
      # sending KILL signal to processes that could not finish 
      echo "Sending KILL signal to rest of $PACKAGENAME processes"
      kill -KILL $LX86_PROCS 2>/dev/null
    fi
  elif [ -e "$POWERVM_LX86_PATH/etc/.sw_installed_successfully" -a -x "$RUNX86" ] ; then
    echo "Changing x86 runlevel"
    cd "$POWERVM_LX86_PATH"
    # we will have two blogd instances using the same /dev/blog
    # creating boot.msg in the x86 world will prevent confusion
    if [ ! -e "$POWERVM_LX86_PATH/var/log/boot.msg" ] ; then
      touch "$POWERVM_LX86_PATH/var/log/boot.msg" &>/dev/null
    fi
    set `/sbin/runlevel`
    export PREVLEVEL=$1
    export RUNLEVEL=$2
    if [ -z "$PREVLEVEL" -o -z "$RUNLEVEL" ] ;
    then
      log_failure_msg "[$0][Error: 0004] Error changing x86 runlevel."
      exit 1
    fi 

    # halt and boot states are handled by main product init script
    if [ "$PREVLEVEL" = "N" -o "$RUNLEVEL" = "0" ] ; then
      log_success_msg "x86 runlevel change processed"
      return
    fi
    if [ -e "/etc/SuSE-release" ] ;
    then
      # SuSE rc wants the runlevels in environment variables
      THECOMMAND="$RUNX86 /etc/init.d/rc"
    else
      # RedHat rc wants the new runlevel as argument
      THECOMMAND="$RUNX86 /etc/rc.d/rc $RUNLEVEL"
    fi

    RC_TIMEOUT=25
    ${THECOMMAND} &
    RC_PID=$!

    RC_COUNTER=0
    while true ; do
      if [ ${RC_COUNTER} -lt ${RC_TIMEOUT} ] ; then
        if ps ${RC_PID} &>/dev/null ; then
          # rc is still running, lets wait 1 more sec
          sleep 1
          ((RC_COUNTER=RC_COUNTER+1))
        else
          # rc's finished
          break
        fi
      else
        # rc is taking too long to run, RC_TIMEOUT secs have passed
        # lets continue and let rc run in the background
        echo " continuing in the background"
        break
      fi
    done
  fi
}

# LOCKFILE will have been defined by the calling script (rc1, rc2 etc).
# On RHEL systems, these files are created to tell the init mechanism that
# the service has been started.

case "$1" in
start)
  # Things we should do on startup:
  check_privileges
  run_subject_rc
  [ -e "/etc/redhat-release" ] && touch $LOCKFILE
  exit 0
;;

stop)
  # We call the same functions on stop; these do the appropriate runlevel switches for us
  check_privileges
  run_subject_rc
  [ -e "/etc/redhat-release" ] && rm -f $LOCKFILE
  exit 0
;;

*)
  echo "Usage: $0 {start}";
  exit 3
;;

esac
exit 0
# end of powervm-lx86_runlevel

