check_health/sources/lib/platform/hp-ux/check_hpux_lunpaths.sh
2018-10-28 21:56:14 +01:00

273 lines
9.1 KiB
Bash

#!/usr/bin/env ksh
#******************************************************************************
# @(#) check_hpux_lunpaths.sh
#******************************************************************************
# @(#) Copyright (C) 2017 by KUDOS BVBA (info@kudos.be). 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 3 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
#******************************************************************************
#
# DOCUMENTATION (MAIN)
# -----------------------------------------------------------------------------
# @(#) MAIN: check_hpux_lunpaths
# DOES: see _show_usage()
# EXPECTS: see _show_usage()
# REQUIRES: data_space2comma(), init_hc(), log_hc(), warn()
#
# @(#) HISTORY:
# @(#) 2017-12-20: initial version [Patrick Van der Veken]
# @(#) 2018-18-22: reworked discovery routine (accommdate large number of LUNS)
# @(#) [Patrick Van der Veken]
# -----------------------------------------------------------------------------
# DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
#******************************************************************************
# -----------------------------------------------------------------------------
function check_hpux_lunpaths
{
# ------------------------- CONFIGURATION starts here -------------------------
typeset _IOSCAN_BIN="/usr/sbin/ioscan"
typeset _IOSCAN_OPTS="-C disk -P wwid"
typeset _SCSIMGR_BIN="/usr/sbin/scsimgr"
typeset _SCSIMGR_OPTS="-v get_info all_lun"
typeset _VERSION="2018-10-22" # YYYY-MM-DD
typeset _SUPPORTED_PLATFORMS="HP-UX" # uname -s match
# ------------------------- CONFIGURATION ends here ---------------------------
# set defaults
(( ARG_DEBUG != 0 && ARG_DEBUG_LEVEL > 0 )) && set ${DEBUG_OPTS}
init_hc "$0" "${_SUPPORTED_PLATFORMS}" "${_VERSION}"
typeset _ARGS=$(data_space2comma "$*")
typeset _ARG=""
typeset _MSG=""
typeset _STC=0
typeset _LOG_HEALTHY=0
typeset _TMP1_FILE="${TMP_DIR}/.$0.ioscan_tmp.$$"
typeset _TMP2_FILE="${TMP_DIR}/.$0.scsimgr_tmp.$$"
typeset _HW_PATH=""
typeset _ACTIVE_PATH_COUNT=""
typeset _ALL_PATH_COUNT=""
typeset _FAILED_PATH_COUNT=""
typeset _STANDBY_PATH_COUNT=""
typeset _WWID=""
# handle arguments (originally comma-separated)
for _ARG in ${_ARGS}
do
case "${_ARG}" in
help)
_show_usage $0 ${_VERSION} ${_CONFIG_FILE} && return 0
;;
esac
done
# log_healthy
(( ARG_LOG_HEALTHY > 0 )) && _LOG_HEALTHY=1
if (( _LOG_HEALTHY > 0 ))
then
if (( ARG_LOG > 0 ))
then
log "logging/showing passed health checks"
else
log "showing passed health checks (but not logging)"
fi
else
log "not logging/showing passed health checks"
fi
# set local trap for cleanup
# shellcheck disable=SC2064
trap "[[ -f ${_TMP1_FILE} ]] && rm -f ${_TMP1_FILE} >/dev/null 2>&1;
[[ -f ${_TMP2_FILE} ]] && rm -f ${_TMP2_FILE} >/dev/null 2>&1;
return 0" 0
# shellcheck disable=SC2064
trap "[[ -f ${_TMP1_FILE} ]] && rm -f ${_TMP1_FILE} >/dev/null 2>&1;
[[ -f ${_TMP2_FILE} ]] && rm -f ${_TMP2_FILE} >/dev/null 2>&1;
return 1" 1 2 3 15
# check required tools
if [[ ! -x ${_IOSCAN_BIN} ]]
then
warn "${_IOSCAN_BIN} is not installed here"
return 1
fi
if [[ ! -x ${_SCSIMGR_BIN} ]]
then
warn "${_SCSIMGR_BIN} is not installed here"
return 1
fi
# check TMP_FILEs
: >${_TMP1_FILE}
(( $? > 0 )) && {
warn "failed to create temporary file at ${_TMP1_FILE}"
return 1
}
: >${_TMP2_FILE}
(( $? > 0 )) && {
warn "failed to create temporary file at ${_TMP2_FILE}"
return 1
}
# get all disk LUNs
(( ARG_DEBUG != 0 )) && debug "collecting ioscan information"
print "=== ioscan ===" >>${HC_STDOUT_LOG}
${_IOSCAN_BIN} ${_IOSCAN_OPTS} >${_TMP1_FILE} 2>>${HC_STDERR_LOG}
if (( $? > 0 ))
then
_MSG="unable to gather ioscan information"
log_hc "$0" 1 "${_MSG}"
# dump debug info
(( ARG_DEBUG != 0 && ARG_DEBUG_LEVEL > 0 )) && dump_logs
return 0
fi
# collect scsimgr info for all LUNs
(( ARG_DEBUG != 0 )) && debug "collecting scsimgr information"
${_SCSIMGR_BIN} ${_SCSIMGR_OPTS} >${_TMP2_FILE} 2>>${HC_STDERR_LOG}
if (( $? > 0 ))
then
_MSG="unable to gather scsimgr information"
log_hc "$0" 1 "${_MSG}"
# dump debug info
(( ARG_DEBUG != 0 && ARG_DEBUG_LEVEL > 0 )) && dump_logs
return 0
fi
# parse ioscan + scsimgr results (WWID is the glue)
(( ARG_DEBUG != 0 )) && debug "glueing ioscan & scsimgr information together"
awk 'BEGIN { wwid = ""; active_paths = ""; all_paths = ""; failed_paths = ""; standby_paths = ""; }
{
# parse ioscan file (build disks[] array)
#Class I H/W Path wwid
#===============================
#disk 4 64000/0xfa00/0x2 0x60060e8007e2b1000030e2b10000bb68
#disk 5 64000/0xfa00/0x3 0x60060e8007e2b1000030e2b100006040
if (FILENAME ~ /ioscan/) {
if ($0 ~ /^disk/) {
disks[$4] = $3;
}
}
# parse scsimgr file (build paths_*[] arrays)
if (FILENAME ~ /scsimgr/) {
# parse until end of stanza (=empty line)
if ($0 ~ /^World Wide Identifier/ ) {
split ($0, line, "=");
wwid = line[2];
gsub (/ /,"", wwid);
getline;
while ($0 !~ /^$/) {
if ($0 ~ /^LUN path count/) {
split ($0, line, "=");
all_paths = line[2];
gsub (/ /,"", all_paths);
}
if ($0 ~ /^Active LUN paths/) {
split ($0, line, "=");
active_paths = line[2];
gsub (/ /,"", active_paths);
}
if ($0 ~ /^Failed LUN paths/) {
split ($0, line, "=");
failed_paths = line[2];
gsub (/ /,"", failed_paths);
}
if ($0 ~ /^Standby LUN paths/) {
split ($0, line, "=");
standby_paths = line[2];
gsub (/ /,"", standby_paths);
}
if (wwid != "" &&
active_paths != "" &&
all_paths != "" &&
failed_paths != "" &&
standby_paths != "") {
paths_active[wwid] = active_paths;
paths_all[wwid] = all_paths;
paths_failed[wwid] = failed_paths;
paths_standby[wwid] = standby_paths;
# reset variables
wwid = ""; active_paths = "";
all_paths = ""; failed_paths = "";
standby_paths = "";
}
getline;
}
}
}
}
END {
# loop over all disk LUNs to display their SCSI attributes
for (wwid in disks) {
print wwid "|" disks[wwid] "|" paths_active[wwid] "|" paths_all[wwid] "|" paths_failed[wwid] "|" paths_standby[wwid]
}
}' ${_TMP1_FILE} ${_TMP2_FILE} 2>/dev/null |\
while IFS='|' read -r _WWID _HW_PATH _ACTIVE_PATH_COUNT _ALL_PATH_COUNT _FAILED_PATH_COUNT _STANDBY_PATH_COUNT
do
if [[ -z "${_ACTIVE_PATH_COUNT}" ]] ||
[[ -z "${_ALL_PATH_COUNT}" ]] ||
[[ -z "${_FAILED_PATH_COUNT}" ]] ||
[[ -z "${_STANDBY_PATH_COUNT}" ]]
then
warn "missing info for ${_HW_PATH}, skipping LUN"
continue
fi
# take standby paths out of the total path count (non-cabled FC ports)
_ALL_PATH_COUNT=$(( _ALL_PATH_COUNT - _STANDBY_PATH_COUNT ))
# check for failed paths
if (( _FAILED_PATH_COUNT > 0 ))
then
_MSG="${_HW_PATH}: ${_FAILED_PATH_COUNT} failed lunpath(s)"
_STC=1
else
_MSG="${_HW_PATH}: 0 failed lunpath(s)"
_STC=0
fi
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}" ${_FAILED_PATH_COUNT} ${_ALL_PATH_COUNT}
fi
done
# save ioscan info for posterity
printf "=== ioscan ===" >>${HC_STDOUT_LOG}
cat ${_TMP1_FILE} >>${HC_STDOUT_LOG}
# save scsimgr info for posterity
printf "\n\n=== scsimgr ===" >>${HC_STDOUT_LOG}
cat ${_TMP2_FILE} >>${HC_STDOUT_LOG}
return 0
}
# -----------------------------------------------------------------------------
function _show_usage
{
cat <<- EOT
NAME : $1
VERSION : $2
PURPOSE : Check the active and failed (non-active) lunpaths of DISK devices
EOT
return 0
}
#******************************************************************************
# END of script
#******************************************************************************