#!/bin/env ksh #****************************************************************************** # @(#) handle_failed_lunpaths.sh #****************************************************************************** # @(#) Copyright (C) 2014 by KUDOS BVBA . All rights reserved. # # This program is a free software; you can redistribute it and/or modify # it under the same terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details #****************************************************************************** # @(#) MAIN: handle_failed_lunpaths.sh # DOES: simple script to show and/or remove failed lunpaths (HP-UX 11.31/Agile) # EXPECTS: (see --help for more options) # REQUIRES: check_platform(), check_exec_user(), die(), display_usage(), # do_cleanup(), log(), warn() # For other pre-requisites see the documentation in display_usage() #****************************************************************************** #****************************************************************************** # DATA structures #****************************************************************************** # ------------------------- CONFIGURATION starts here ------------------------- # define the V.R.F (version/release/fix) HPUX_VRF="1.0.0" # UNIX user this script should run as EXEC_USER="root" # location of log directory (default) LOG_DIR="/var/adm" # location of temporary working storage TMP_DIR="/var/tmp" # ------------------------- CONFIGURATION ends here --------------------------- # miscelleaneous PATH=${PATH}:/usr/bin:/usr/sbin:/usr/local/bin SCRIPT_NAME=$(basename $0) SCRIPT_DIR=$(dirname $0) HOST_NAME=$(hostname) TMP_FILE="${TMP_DIR}/.${SCRIPT_NAME}.$$" LOG_FILE="${LOG_DIR}/${SCRIPT_NAME}.log" # command-line parameters ARG_REMOVE=0 # remove failed lunpath (0=no|1=yes; default: 0) ARG_DISK="" ARG_SKIP_CRA="" # skip_cra option for 'scsimgr disable' ARG_LOG=1 # logging is on by default ARG_VERBOSE=1 # STDOUT is on by default #****************************************************************************** # FUNCTION routines #****************************************************************************** # ----------------------------------------------------------------------------- function check_platform { if [[ "$(uname -s)" != "HP-UX" ]] then print -u2 "ERROR: must be run on a HP-UX system" exit 1 fi if [[ "$(uname -r)" != "B.11.31" ]] then print -u2 "ERROR: must be run on version B.11.31" exit 1 fi return 0 } # ----------------------------------------------------------------------------- function check_exec_user { (IFS='()'; set -- $(id); print $2) | read UID if [[ "${UID}" != "${EXEC_USER}" ]] then print -u2 "ERROR: must be run as user '${EXEC_USER}'" exit 1 fi return 0 } # ----------------------------------------------------------------------------- # log an ERROR: message (via ARG) and exit. function die { NOW="$(date '+%d-%h-%Y %H:%M:%S')" # process ARG (if any) if [[ -n "$1" ]] then if (( ARG_LOG != 0 )) then print - "$*" | while read LOG_LINE do # filter leading 'ERROR:' LOG_LINE="${LOG_LINE#ERROR: *}" print "${NOW}: ERROR: [$$]:" "${LOG_LINE}" >> ${LOG_FILE} done fi print - "$*" | while read LOG_LINE do # filter leading 'ERROR:' LOG_LINE="${LOG_LINE#ERROR: *}" print -u2 "ERROR:" "${LOG_LINE}" done fi # handle alert (( ARG_SEND_ALERT != 0 )) && print "${LOG_STDIN}" | send_alert "$*" # finish up work do_cleanup exit 1 } # ----------------------------------------------------------------------------- function display_usage { cat << EOT **** ${SCRIPT_NAME} **** **** (c) KUDOS BVBA - UNIX (Patrick Van der Veken) **** Show or removes failed LUNpaths. Only works on HP-UX 11.31 with agile DSFs. Syntax: ${SCRIPT_DIR}/${SCRIPT_NAME} [--help] | [--version] | [--no-log] ( [--remove] [--skip_cra] ) [--disk= ] Parameters: --disk : operate only on the given disk/lun, otherwise operate on all disks/luns --no-log : do not log any messages to the script log file. --remove : do the actual removal of the failed paths (default: show only) --skip-cra : perform 'scsimgr disable' actions with CRA (Critical Resource Analysis) --version : show the script version/release/fix EOT return 0 } # ----------------------------------------------------------------------------- function do_cleanup { log "performing cleanup ..." # remove temporary file(s) if [[ -f ${TMP_FILE} ]] then rm -f ${TMP_FILE} >/dev/null log "${TMP_FILE} temporary file removed" fi log "*** finish of ${SCRIPT_NAME} [${CMD_LINE}] ***" return 0 } # ----------------------------------------------------------------------------- # log an INFO: message (via ARG). function log { NOW="$(date '+%d-%h-%Y %H:%M:%S')" # process ARG (if any) if [[ -n "$1" ]] then if (( ARG_LOG != 0 )) then print - "$*" | while read LOG_LINE do # filter leading 'INFO:' LOG_LINE="${LOG_LINE#INFO: *}" print "${NOW}: INFO: [$$]:" "${LOG_LINE}" >> ${LOG_FILE} done fi if (( ARG_VERBOSE != 0 )) then print - "$*" | while read LOG_LINE do # filter leading 'INFO:' LOG_LINE="${LOG_LINE#INFO: *}" print "INFO:" "${LOG_LINE}" done fi fi return 0 } # ----------------------------------------------------------------------------- # log a WARN: message (via ARG). function warn { NOW="$(date '+%d-%h-%Y %H:%M:%S')" # process ARG (if any) if [[ -n "$1" ]] then if (( ARG_LOG != 0 )) then print - "$*" | while read LOG_LINE do # filter leading 'WARN:' LOG_LINE="${LOG_LINE#WARN: *}" print "${NOW}: WARN: [$$]:" "${LOG_LINE}" >>${LOG_FILE} done fi if (( ARG_VERBOSE != 0 )) then print - "$*" | while read LOG_LINE do # filter leading 'WARN:' LOG_LINE="${LOG_LINE#WARN: *}" print "WARN:" "${LOG_LINE}" done fi fi return 0 } #****************************************************************************** # MAIN routine #****************************************************************************** # parse arguments/parameters CMD_LINE="$@" for PARAMETER in ${CMD_LINE} do case ${PARAMETER} in -disk*) ARG_DISK="${PARAMETER#-disk=}" ;; --disk*) ARG_DISK="${PARAMETER#--disk=}" ;; -remove|--remove) ARG_REMOVE=1 shift ;; -skip-cra|--skip-cra) ARG_SKIP_CRA=" skip_cra" ;; -V|-version|--version) print "INFO: $0: ${HPUX_VRF}" exit 0 ;; \? |-h|-help|--help) display_usage exit 0 ;; esac done # startup checks check_platform && check_exec_user # catch shell signals trap 'do_cleanup; exit' 1 2 3 15 log "*** start of ${SCRIPT_NAME} [${CMD_LINE}] ***" (( ARG_LOG != 0 )) && log "logging takes places in ${LOG_FILE}" # set disk list if [[ -z "${ARG_DISK}" ]] then log "operating on ALL disks/luns" ls -1 /dev/rdisk/disk* 2>/dev/null >${TMP_FILE} else ls -1 /dev/rdisk/disk* >/dev/null 2>/dev/null if (( $? != 0 )) then die "disk ${ARG_DISK} does not exist?" else log "operating on a specific disk/lun: ${ARG_DISK}" print "/dev/rdisk/${ARG_DISK}" >${TMP_FILE} fi fi (( ARG_REMOVE == 0 )) && log "PREVIEW only: showing failed paths without removal" # perform the magic while read DISK do scsimgr -p lun_map -D ${DISK} 2>/dev/null | grep -i 'failed' 2>/dev/null |\ while read SCSI_LINE do log "${SCSI_LINE}" HW_PATH=$(print "${SCSI_LINE}" | cut -f3 -d':') if (( ARG_REMOVE == 1 )) then scsimgr -f disable -H "${HW_PATH}" ${ARG_SKIP_CRA} RC=$? if (( RC == 0 )) then log "disabled ${HW_PATH}" rmsf -H "${HW_PATH}" 2>/dev/null RC=$? if (( RC == 0)) then log "removed ${HW_PATH}" else warn "failed to remove ${HW_PATH}" fi else warn "failed to disable ${HW_PATH}" fi fi done done <${TMP_FILE} # finish up work do_cleanup #****************************************************************************** # END of script #******************************************************************************