#!/bin/ksh
#
# 2010/07/22 17:36:17 smatpadi Exp $ Copyr (c) 1997,2010  Oracle
#
#
# rootpre.sh
#
# This script is intended to be run by root before ORACLE_OWNER runs
# the Installer to install ORACLE products.
#
# This script should be run by root from the directory where this script
# resides.  If root wishes to run this script from another directory,
# then root must set the environment variable is ROOTPRE_DIR (see below).
#
# rootpre.sh performs configuration tasks for 3 AIX components: 
#   - Asynchronous I/O subsystem s made available
#   - sets permissions on HACMP and PSSP sockets
#
#
# ENVIRONMENT:
#
#    LOG 	
#	If root wishes to log diagnostic output generated by this script, 
#	set environment variable LOG to the pathname of the log file.
#
#    ROOTPRE_DIR 	
#	If root wishes to run rootpre.sh from a directory other than that
#	in which rootpre.sh resides, set ROOTPRE_DIR to the directory where
#	rootpre.sh resides.
#

#====================================================================================
#======================= setup environment ==========================================
#====================================================================================
INSTALL_DIR=/etc
ORACLUSTER_DIR=/opt/ORCLcluster
LIBSKGXNR=libskgxnr.so
SKGXN_VER=2
#-----------------------------------------------------
#--- define the logging functions 
#-----------------------------------------------------
TIME_STAMP=`/bin/date +%y-%0m-%0d.%0H:%0M:%0S`

#--- If ROOTPRE_DIR is not set, then set it to '.' (viz., current directory).
case $ROOTPRE_DIR in
    "") ROOTPRE_DIR=./ ;;
esac

#Check where the rootpre base dir is present
if [ -f ${ROOTPRE_DIR}/ORCLcluster/lib/${LIBSKGXNR} ]; then
     ROOTPRE_DIR="${ROOTPRE_DIR}/";
elif [ -f ${ROOTPRE_DIR}/rootpre/ORCLcluster/lib/${LIBSKGXNR} ]; then
     ROOTPRE_DIR="${ROOTPRE_DIR}/rootpre";
else
     ROOTPRE_DIR="${ROOTPRE_DIR}/source/crs/Disk1/rootpre";
fi

#--- If LOG is not set, then set it
case $LOG in
    "") LOG=/tmp/rootpre.out_${TIME_STAMP} ;;
esac

if [ -f ${LOG} ]
 then
   if [ ! -w ${LOG} ]
   then
      echo "Log file ${LOG} is not writeable."
      echo "Please specify a writeable file using the LOG environment variable."
      exit
   fi
   else
    if [ ! -w `dirname ${LOG}` ]
    then
      echo "Log file ${LOG} is not writeable."
      echo "Please specify a writeable file using the LOG environment variable."
      exit
    fi
fi

#--- message to LOG file
log () {
  echo "$*" 2>&1 >> ${LOG}
}

#--- message to LOG file and console
log_con () {
  echo "$*" | tee -a ${LOG}
}

#--- echo command to log and execute
log_do () {
  echo "CMD: $*" 2>&1 >> ${LOG}
  $* 2>&1 >> ${LOG}
  if [ $? -ne 0 ]; then
     return -1
  else
     return 0
  fi
}

#--- message to LOG file and console then return error
error_out () {
  if [ "$*" != "" ]; then
    log_con "$*"
  fi
  log_con "Aborting pre-installation procedure. Installations of Oracle may fail."
  exit 1
}



CHOWN=/bin/chown
CHMOD=/bin/chmod
CHGRP=/bin/chgrp
CP=/bin/cp
MV=/bin/mv
MKDIR=/bin/mkdir
CHITAB=/usr/sbin/chitab
MKITAB=/usr/sbin/mkitab
LSITAB=/usr/sbin/lsitab
RMITAB=/usr/sbin/rmitab
LN=/bin/ln
LNSF="/bin/ln -sf "
LS=/bin/ls
AWK=/bin/awk
PS=/bin/ps
GREP=/bin/grep
LSDEV=/usr/sbin/lsdev
MKDEV=/usr/sbin/mkdev
CHDEV=/usr/sbin/chdev
LSATTR=/usr/sbin/lsattr
MKGROUP=/bin/mkgroup
ODMGET=/bin/odmget
IDCMD=/usr/bin/id
UNAME=/bin/uname
#--- lsgroup is in /usr/sbin or /bin
LSGROUP=/usr/sbin/lsgroup
if [ ! -f ${LSGROUP} ]; then
   LSGROUP=/bin/lsgroup
fi

LC_ALL=C
export LC_ALL


#---
#--- Find out which os-level and release we're on 
#---
OSVER=`$UNAME -v`
OSREL=`$UNAME -r`

#--- dump script environment information to the log
log_con "$0 output will be logged in ${LOG}"
log "/bin/uname -a: `/bin/uname -a`"
log "OSVER: ${OSVER}"
log "OSREL: ${OSREL}"
log "\nEnvironment:\n------------"
log "`/bin/env`"
log "------------\n"


#====================================================================================
#======================= define functions ===========================================
#====================================================================================

#---
#--- Function : check_prereq
#--- checks if prerequisites for running the script are met:
#---   - running as root.
#---   - if running at AIX 6 or greater
#---       make sure we're running in global WPAR
#---
  function check_prereq
  {
    RUID=`$IDCMD|$AWK -F\( '{print $2}'|$AWK -F\) '{print $1}'`

    if [ ${RUID} != "root" ];then
      error_out "You must be logged in as root to run this script"
    fi

#   if we're running under AIX 6 then we could be running in a WPAR. If we are
#   then we must be running from the global WPAR. If we're not running in a WPAR
#   the result is the same, uname -W will return 0.
    if [ ${OSVER} -eq '6' ] ; then
      WPARID=`$UNAME -W`

      if [ ${WPARID} -ne '0' ] ;then
         error_out "This script must be run from within the Global WPAR"
      fi
    fi
  }

#---
#--- Function : check_cssinuse()
#--- checks if ocssd is running. libskgxn is being used.
#---
  function check_cssinuse
  {
    # check if OCSSD is being run
    ${PS} -eaf | ${GREP} -c ocssd.bi[n]
  }


# check prerequistes for executing this script
check_prereq


#====================================================================================
#======================= configure Asynchronous I/O =================================
#====================================================================================

#--- function to check the autoconfig value on an AIO device
is_autoconfig_available () {
   DEVICE=${1}
   VALUE=`$LSATTR -E -l ${DEVICE}|${GREP} autoconfig|${AWK} '{print $2}'`
   if [ "${VALUE}" = "available" ]; then
      return 1
   else 
      return -1
   fi
}

#--- In AIX 6.1 and newer AIO is already configured and ioo is used, 
#---    not chdev to modify AIO configuration 
if [ $OSVER -lt 6 ]; then
  log_con "\nConfiguring Asynchronous I/O...."
  AIO=`${LSDEV} -C -t aio|${AWK} '{print $2}'`
  case ${AIO} in
    *Available*) log_con "Asynchronous I/O is already defined"
               is_autoconfig_available "aio0"
               if [ $? -ne 1 ]; then
                  log_con "Setting autoconfig to available for aio0"
                  log_do "${CHDEV} -P -l aio0 -a autoconfig=available"
               fi
               ;;
      *Defined*) log_do "${MKDEV} -l aio0"
               log_do "${CHDEV} -P -l aio0 -a autoconfig=available"
               ;;
            *) log_con "Asynchronous I/O is not installed on this system."
               log_con "You will need to install it, and either configure it yourself using"
               log_con "'smit aio' or rerun the Oracle root installation procedure."
               ;;
  esac

  #--- configure POSIX AIO if AIX 5.2 or greater, we may want to use it
  if [ ${OSVER}${OSREL} -ge 52 ]; then
    log_con "\nConfiguring POSIX Asynchronous I/O...."
    POSIX_AIO=`${LSDEV} -C -t posix_aio|${AWK} '{print $2}'`
    case ${POSIX_AIO} in
      *Available*) log_con "Posix Asynchronous I/O is already defined"
                   is_autoconfig_available "posix_aio0"
                   if [ $? -ne 1 ]; then
                      log_con "Setting autoconfig to available for posix_aio0"
                      log_do "${CHDEV} -P -l posix_aio0 -a autoconfig=available"
                   fi
                   ;;
        *Defined*) log_do "${MKDEV} -l posix_aio0"
                   log_do "${CHDEV} -P -l posix_aio0 -a autoconfig=available"
                   ;;
                *) log_con "Posix Asynchronous I/O is not installed on this system."
                   log_con "You will need to install it, and either configure it yourself using"
                   log_con "'smit aio' or rerun the Oracle root installation procedure."
                   ;;
    esac
  fi
fi

#====================================================================================
#======================= configure HACMP ============================================
#====================================================================================
#
# To install Oracle CRS we need to ensure that the socket used by hags is present in 
# /var/ha/soc/<subsystem>socket.<partition name> has read/write 
# permissions for the group hagsuser. For HACMP clusters, execute perms 
# is needed for cldomain.
#

log_con "\nChecking if group services should be configured...."


[ -z "${ODMDIR}" ] &&  ODMDIR=/etc/objrepos
isHACMP=`${ODMGET} -q name=cluster.es.clvm.rte lpp 2>/dev/null | wc -l`
if [ ${isHACMP} -eq 0 ]; then 
   isHACMP=`${ODMGET} -q name=cluster.es.client.lib lpp 2>/dev/null | wc -l`
fi 
log "ODMDIR=${ODMDIR}, isHACMP=${isHACMP}"
if [ ${isHACMP} -eq 0 ]; then
   log_con "Nothing to configure."
fi

if [ ! ${isHACMP} -eq 0 ]; then
   if [ ! -f /usr/sbin/cluster/utilities/cldomain ]; then
     error_out "/usr/sbin/cluster/utilities/cldomain: file not found"
   fi
   log_do "${CHMOD} +x /usr/sbin/cluster/utilities/cldomain"
   if [ ! $? -eq 0 ]; then
     error_out "Cannot add execute perms for /usr/sbin/cluster/utilities/cldomain"
   fi
fi

#--- Function to set the permissions on the HACMP socket
cluster_config () {
  HAGS_SOCKET="$*"
  SOCKET_CHANGED=""
  #--- Check if the socket is present.
  if [ ! -r ${HAGS_SOCKET} ]; then
    log "${HAGS_SOCKET}: No such file or directory."
    error_out "Please make sure that the group services subsystem is active."
  fi
  #--- Check if group has already been set to hagsuser, if not set it.
  if [ `${LS} -l ${HAGS_SOCKET}|${GREP} -c hagsuser` -eq 0 ]; then
     log_do "${CHGRP} hagsuser ${HAGS_SOCKET}"
     if [ ! $? -eq 0 ]; then
       error_out "Unable to change the group ownership of ${HAGS_SOCKET}."
     fi
     SOCKET_CHANGED="TRUE"
  fi
  #--- Check if group permission is already rw, if not set it.
  if [ `${LS} -l ${HAGS_SOCKET}|${GREP} -c "^s...rw"` -eq 0 ]; then
     log_do "${CHMOD} g+rw ${HAGS_SOCKET}"
     if [ ! $? -eq 0 ]; then
       error_out "Unable to change the group permissions of ${HAGS_SOCKET}"
     fi
     log_do "${LS} -l ${HAGS_SOCKET}"
     SOCKET_CHANGED="TRUE"
  fi
  if [ "${SOCKET_CHANGED}" = "TRUE" ]; then
     #--- something changed, so group services will need to be restarted
     log_con "\nThe group or permissions of the group services socket have changed."
     return -1
  else
     return 0
  fi
}

#--- function to create group hagsuser if it doesn't already exist
create_hagsuser () {
   log_do "${LSGROUP} hagsuser"
   if [ $? -ne 0 ]; then
      log_con "Creating required group for group services: hagsuser"
      log_con "Please add your Oracle userid to the group: hagsuser"
      log_do "$MKGROUP -A hagsuser"
   else
      log_con "Please confirm your Oracle Clusterware Userid is a member of the group: hagsuser"
   fi
}

#--- check if CSS is running
if [ ! ${isHACMP} -eq 0 ]; then
   if [ `check_cssinuse` -gt 0 ]
      then
        log_con   "Oracle Clusterware may be in use."
        error_out "Shutdown the Oracle clusterware and rerun the rootpre.sh script."
   fi
fi

#--- create hagsuser group
if [ ! ${isHACMP} -eq 0 ]; then
  create_hagsuser
  log_con "Configuring HACMP group services socket for possible use by Oracle."
  PARTITION_NAME=`/usr/sbin/cluster/utilities/cldomain 2>&1`
  if [ -z "${PARTITION_NAME}" ]; then
    error_out "Unable to find default partition name -- HACMP."
  fi
  cluster_config "/var/ha/soc/grpsvcsdsocket.${PARTITION_NAME}"
  if [ $? -ne 0 ]; then
     log_con "\nPlease stop and restart HACMP before trying to use Oracle.\n"
  fi
fi

if [ ! ${isHACMP} -eq 0 ]; then

   CMDDIR=`dirname $0`

   if [ "$CMDDIR" = "." ];then
      CMDDIR=`pwd`;
   fi
   # Replace relative path with fully qualified path.
   if [ ! "`echo $CMDDIR|grep '^/'`" ];then
      CMDDIR=`pwd`/$CMDDIR;
   fi

   # CMDDIR

   if [ -f ${CMDDIR}/ORCLcluster/lib/${LIBSKGXNR} ]; then
      CMDDIR="${CMDDIR}/";
   elif [ -f ${CMDDIR}/rootpre/ORCLcluster/lib/${LIBSKGXNR} ]; then
      CMDDIR="${CMDDIR}/rootpre";
   else
      CMDDIR="${CMDDIR}/source/crs/Disk1/rootpre";
   fi

   #Create the /opt/ORCLcluster directory structure
   for DIR in bin lib lib32
   do
       if [ ! -d $ORACLUSTER_DIR/${DIR} ]; then
	  $MKDIR -p $ORACLUSTER_DIR/${DIR}
       fi
   done

   # Ensure that any older copy of the library are not locked in kernel
   /usr/sbin/slibclean

   # Get the effective group id of root and change ownership to root:gid
   GROUP=`$IDCMD -gn root`
   if [ x$GROUP = "x" ]; then
      GROUP=system
   fi

   for LIB in lib lib32
   do
     if [ -f ${CMDDIR}/ORCLcluster/${LIB}/${LIBSKGXNR} ]; then
       # Copy the SKGXN libraries from the SHIPHOME 
       $CP $CMDDIR/ORCLcluster/${LIB}/${LIBSKGXNR} $ORACLUSTER_DIR/${LIB}/${LIBSKGXNR}
       if [ $? != 0 ]; then
          error_out "Copy of $CMDDIR/ORCLcluster/${LIB}/${LIBSKGXNR} failed."
       fi
     else
       # Copy the SKGXN libraries from the ORA_CRS_HOME/$LIB (cloned install env.)
       $CP $CMDDIR/../../${LIB}/${LIBSKGXNR} $ORACLUSTER_DIR/${LIB}/${LIBSKGXNR}
       if [ $? != 0 ]; then
          error_out "Copy of $CMDDIR/ORCLcluster/${LIB}/${LIBSKGXNR} failed."
       fi
     fi

     $CHOWN root:$GROUP $ORACLUSTER_DIR/${LIB}/libskgxnr.*
     $CHMOD 755 $ORACLUSTER_DIR/${LIB}/libskgxnr.*

     $LNSF $ORACLUSTER_DIR/${LIB}/${LIBSKGXNR} $ORACLUSTER_DIR/${LIB}/libskgxn${SKGXN_VER}.so
   done
fi