#! /usr/bin/ksh
# @(#) $Header: hparrayrc,v 78.1 96/02/08 19:50:15 ssa Exp $
##########################################################################
#                                                                        #
# HP disk array start up script                                          #
#                                                                        #
# This script performs the following required start-up functions for     #
# disk arrays:                                                           #
#                                                                        #
#   Start the disk array monitor daemon "arraymond".                     #
#   Verify HPC2400 disk array parity data.                               #
#                                                                        #
# If the host system was NOT shutdown properly then scan for and repair  #
# inconsistent RAID parity on all configured HPC2400 disk array LUNs.    #
#                                                                        #
##########################################################################


##########################################################################
#                                                                        #
# RAID parity scan and repair                                            #
#                                                                        #
##########################################################################
#
# In certain modes of operation, the C2425 and C2430 disk arrays store 
# redundant information from which data can be reconstructed in the event 
# of a disk drive failure.  This information is often referred to as  
# RAID parity.  Since this information is redundant, there is a small
# possibility that it can become inconsistent, under extreme operating
# conditions, such as an unanticipated power failure. An attempt to
# reconstruct data from inconsistent parity will result in incorrect data.
# To minimize the possibility of reconstructing incorrect data, it is
# important to detect and correct inconsistent parity before a drive
# failure occurs.
# 
# When inconsistent parity is found, there is no way of knowing whether
# the parity information or the data itself is wrong, therefore, the
# correction is always applied to the parity.  Data with inconsistent
# parity does not mean that the data is incorrect.  It indicates that a
# transaction altering the data and parity was in progress when an event
# occurred that prevented the transaction from completing.  The data
# associated with an inconsistent parity that was corrected is as reliable
# as any other data which was being written when the event occurred.
#
# The process of finding and repairing parity inconsistencies on the
# disk array is somewhat time consuming.  The most probable cause of
# inconsistent parity is unanticipated power failure.  Thus, a reasonable
# compromise is reached by performing the parity scan and repair process
# automatically at system boot time, when required.  A facility is also
# provided to allow manual execution of the process on individual arrays
# for situations where it is required.
#
# Three commands are used to implement the parity scan and repair process:
# scn(1M), rpr(1M), and pscan(1M).  Consult the corresponding man pages for
# detailed information on these commands.  These commands and this script
# have been designed to optimize the performance and reliability of the
# parity scan process.  
#
# The parity scan process is performed on all disk arrays marked "dirty". 
# Disk arrays are marked "dirty" when the system is not shut down
# properly [SHUTDOWN(1M)].  
#
. /usr/lbin/hpC2400/arraymon.hdr
#
##########################################################################
#                                                                        #
# Procedure to initiate parallel scans on array devices while the        #
# LUNS on an array device are scanned sequentially.  This results in     #
# the minimum time to complete the scans on a system with multiple       #
# array devices connected.                                               #
#                                                                        #
##########################################################################
#
#
scan_devices()
{
  #
  # For each array device read the devfile from stdin.
  #
  while read VENDR PROD DFILE T1 T2 T3
    do
      #
      # Check for product ID prior to running PSCAN
      #
      if [[ $PROD = "C2430D" ]]
      then
        
        #
        # Get a list of luns configured on the physical device.
        #
        DEV_LUNS=`/usr/bin/awk 'substr($3,11,14) == substr("'$DFILE'",11,14) \
                                {print $3}' \
                                ${UNITS_LIST}`
        #
        # Scan the luns on the device sequentially but initiate scans on
        # multiple devices in background.
        #
        ( for LUN in ${DEV_LUNS}
          do
            PSCAN_FAILURE=0
            ${PERFORM_PARITY_SCAN} -s 0 ${LUN} || PSCAN_FAILURE=1
            if [ ${PSCAN_FAILURE} -eq 1 ]
            then
              /usr/bin/echo "HPC2400 DISK ARRAY PARITY SCAN/REPAIR FAILED." 
              /usr/bin/echo "\"${PERFORM_PARITY_SCAN}\" failed."
              /usr/bin/echo "Wait for any executing parity scan processes to complete."
              /usr/bin/echo "Take corrective action and execute \"pscan(1M)\" on ${LUN}." 
            else
              /usr/bin/echo "${PERFORM_PARITY_SCAN}: ${LUN} - parity scan and repair completed successfully." 
            # perform parity scan 
	    fi
          # for each LUN
          done ) &
      # Check for product ID
      fi
    # do read
    done
}

##########################################################################
#                                                                        #
# Main                                                                   #
#                                                                        #
##########################################################################
  #
  if [ -d ${MISC_DIR} ]
    then
    # Ensure that resource lock files exist
    /usr/bin/touch ${DAEMON_LOCK}
    /usr/bin/touch ${PSCAN_LOCK}
    #
    # Perform the search for arrays.  If the search returns a non-zero
    # exit status then something went wrong with the search and the
    # results of the parity scan will be questionable since it's not
    # clear that all configured disk arrays have been identified.  In this
    # case set the failure flag so that notification of the problem will
    # be given.
    #
    /usr/bin/echo ""
    /usr/bin/date
    ${SCAN_FOR_ARRAYS} 
    ARRAYSCAN_RETURN_VALUE=$?
    if [ ${ARRAYSCAN_RETURN_VALUE} -eq 0 ]
      then
      #
      # Test to ensure that disk array devices were detected
      #
      if [ -s ${DEVS_LIST} ]
        then
        #--------------------------------------------------
        # Start disk array monitor daemon
        #--------------------------------------------------
        if [ -x ${ARRAY_MONITOR_DAEMON} ]
          then
          /usr/bin/echo ""
          /usr/bin/echo "Starting disk array monitor daemon"
          /usr/bin/nohup ${ARRAY_MONITOR_DAEMON} 2>&1 &
        # Start monitor daemon
	fi
        #--------------------------------------------------
        # Start ARMServer daemon
        #--------------------------------------------------
        if [ -x ${ARMSERVER_DAEMON} ]
        then
          /usr/bin/echo ""
          /usr/bin/echo "Starting ARMServer daemon"
          ${ARMSERVER_DAEMON} 2>&1
        fi
        #
        # For each LUN detected, test to see if a parity scan is required.
        # If something goes wrong with the parity scan process, scan_devices
        # will give notification to the user.
        #
        scan_devices < ${DEVS_LIST}
      else
        /usr/bin/echo "No disk array devices were detected."
        /usr/bin/echo "To disable starting the disk array daemons"
        /usr/bin/echo "set HPARRAY_START_STOP=0 in /etc/rc.config.d/hparray."
      # Disk arrays detected
      fi
    else 
      case ${ARRAYSCAN_RETURN_VALUE} in
      -1)  # fatal error
          /usr/bin/echo "SCAN FOR DISK ARRAY'S FAILED."
          /usr/bin/echo "\"${SCAN_FOR_ARRAYS}\" failed."
          /usr/bin/echo "Take corrective action then execute \"${SCAN_FOR_ARRAYS}\" again.\n"
          ;;
      1)  # error encountered during run
          /usr/bin/echo "SCAN FOR DISK ARRAY'S ENCOUNTERED ERRORS."
          /usr/bin/echo "\"${SCAN_FOR_ARRAYS}\" completed with errors."
          /usr/bin/echo "Take corrective action then execute \"${SCAN_FOR_ARRAYS}\" again.\n"
          ;;
      2)  # no disk arrays detected  
          /usr/bin/echo "SCAN FOR DISK ARRAY'S DID NOT DETECT DISK ARRAYS."
          /usr/bin/echo "To disable set HPARRAY_START_STOP=0 in /etc/rc.config.d/hparray."
          ;;
      *)  # unexptected error 
          /usr/bin/echo "SCAN FOR DISK ARRAY'S ENCOUNTERED UNEXPECTED ERRORS."
          /usr/bin/echo "Take corrective action then execute \"${SCAN_FOR_ARRAYS}\" again.\n"
          ;;
      esac
    # Arrayscan succeeded
    fi
  # Test for DAEMON_DIR
  fi
