#!/bin/sh # # Show status of LSI Logic's MegaRAID SAS RAID controllers. # # $FreeBSD$ # # If there is a global system configuration file, suck it in. # if test -r /etc/defaults/periodic.conf; then . /etc/defaults/periodic.conf source_periodic_confs fi # Defaults. : ${daily_status_mfi_raid_enable:=NO} : ${daily_status_mfi_raid_verbose:=NO} : ${daily_status_mfi_raid_persist_logs:=YES} megacli=${megacli:-%%PREFIX%%/sbin/megacli} logdir=${logdir:-/var/log} case "$daily_status_mfi_raid_enable" in [Yy][Ee][Ss]) echo echo 'Checking status of MFI RAID controllers:' ;; *) exit 0 ;; esac if test `id -u` -ne 0; then echo "You must be root to run `basename $0`." >&2 exit 1 fi ADPCOUNT=$(${megacli} -adpCount | \ awk '/Controller Count:/ { gsub("\\.", ""); print $3 }') case ${ADPCOUNT} in 0) echo "Error: Cannot find an adapter." >&2 exit 1 ;; [1-9]|[1-9][0-9]|[1-2][0-9][0-9]) ;; *) echo "Error: Cannot get the number of adapters: ${ADPCOUNT}" >&2 exit 1 ;; esac ADPMINIDX=0 ADPMAXIDX=`expr ${ADPCOUNT} - 1` rc=0 for ctrl in `jot ${ADPCOUNT} ${ADPMINIDX} ${ADPMAXIDX}`; do echo "Adapter: ${ctrl}" # Print summary information. echo "------------------------------------------------------------------------" echo "Physical Drive Information:" echo "ENC SLO DEV SEQ MEC OEC PFC LPF STATE" ${megacli} -PDList -a${ctrl} | \ awk ' BEGIN { E=-1; S=-1; D=-1; s=-1; mec=-1; oec=-1; pfc=-1; lpfeqn=-1; state=""; } /^Enclosure (Number|Device ID):/ { E=$3; } /^Slot Number:/ { S=$3; } /^Device Id:/ { D=$3; } /^Sequence Number:/ { s=$3; } /^Media Error Count:/ { mec=$4; } /^Other Error Count:/ { oec=$4; } /^Predictive Failure Count:/ { pfc=$4; } /^Last Predictive Failure Event Seq Number:/ { lpfeqn=$7 } /^Firmware state:/ { state=$3; } /^$/ { if (E!=-1 && S!=-1 && D!=-1) { printf "%-3d %-3d %-3d %-3d %-3d %-3d %-3d %-3d %s\n", E, S, D, s, mec, oec, pfc, lpfeqn, state; } E=-1; S=-1; D=-1; s=-1; mec=-1; oec=-1; pfc=-1; lpfeqn=-1; state=""; } ' | sort -n -k1 -k2 -k3 echo echo "Virtual Drive Information:" ${megacli} -LDInfo -lall -a${ctrl} | \ awk ' BEGIN { drvs=-1; vd=-1; state=""; name=""; s=-1; strs=-1; rlp=-1; rls=-1; rlq=-1; printf "VD DRV RLP RLS RLQ STS SIZE STATE NAME\n"; } /^Name:/ { sub("^Name:", ""); name=$0; } /^RAID Level:/ { #Primary-1, Secondary-0, RAID Level Qualifier-0 _p=_s=_q=$0; sub(".*Primary-", "", _p); sub(", Secondary.*", "", _p); rlp=_p; sub(".*Secondary-", "", _s); sub(", RAID Level.*", "", _s); rls=_s; sub(".*Qualifier-", "", _q); rlq=_q; } /^Size:/ { sub("^Size:", ""); s=$0; } /^State:/ { state=$2; } /^Stripe Size:/ { strs=$3; } /^Number Of Drives:/ { sub("Drives:", "", $3); drvs=$3; } /^Virtual Disk:/ { if (vd!=-1) { printf "%-3d %-3d %-3d %-3d %-3d %-6s %-11s %-13s %s\n", vd, drvs, rlp, rls, rlq, strs, s, state, name; } drvs=-1; vd=-1; state=""; name=""; s=-1; strs=-1; rlp=-1; rls=-1; rlq=-1; vd=$3; } END { if (vd!=-1) { printf "%-3d %-3d %-3d %-3d %-3d %-6s %-11s %-13s %s\n", vd, drvs, rlp, rls, rlq, strs, s, state, name; } } ' # Print BBU Information, if we found something ${megacli} -AdpBbuCmd -a${ctrl} | \ awk ' BEGIN { type=""; temp=-1; isok="-"; rsoc=-1; asoc=-1; rc=-1; cc=-1; me=-1; } /^BatteryType:/ { type=$2; } /^Temperature:/ { temp=$2; } /^isSOHGood:/ { isok=$2; } /^Relative State of Charge:/ { rsoc=$5; } /^Absolute State of charge:/ { asoc=$5; } /^Remaining Capacity:/ { rc=$3; } /^Cycle Count:/ { cc=$3; } /^Max Error:/ { me=$3; } END { if (type == "") { exit 0 }; printf "\nBBU Information:\n" printf "TYPE TEMP OK RSOC ASOC RC CC ME\n"; printf "%-5s %2dC %-3s %4d%% %4d%% %4dmAh %4d %2d%%\n", type, temp, isok, rsoc, asoc, rc, cc, me; } ' echo # Give very long outputs. case "$daily_status_mfi_raid_verbose" in [Yy][Ee][Ss]) ${megacli} -AdpAllInfo -a${ctrl} ${megacli} -EncInfo -a${ctrl} ${megacli} -PDList -a${ctrl} ${megacli} -LDGetNUm -a${ctrl} ${megacli} -LDInfo -Lall -a${ctrl} ${megacli} -AdpBbuCmd -GetBbuStatus -a${ctrl} ;; *) ;; esac # Diff daily logs. echo "Controller Logs:" ctrl_log=${logdir}/mfi_raid_${ctrl} case "$daily_status_mfi_raid_persist_logs" in [Yy][Ee][Ss]) if test ! -f ${ctrl_log}.today; then touch ${ctrl_log}.today fi mv -f ${ctrl_log}.today ${ctrl_log}.yesterday ;; *) ;; esac ${megacli} -AdpEventLog -GetEvents -f ${ctrl_log}.tmp -a${ctrl} awk ' BEGIN { inrecord=0; } printed=0; /^seqNum: / { inrecord=0; print ""; print "====================================" \ "===================================="; } /^Event Data:/ { inrecord=1; printed=1; } /^seqNum: /, /^Event Data:/ /^===========/ { printed=1; } /^$/ { printed=1; } { if (inrecord && !printed) { printf "\t%s\n", $0; } } ' < ${ctrl_log}.tmp > ${ctrl_log}.today rm -f ${ctrl_log}.tmp # Now show the differences or the entire log. case "$daily_status_mfi_raid_persist_logs" in [Yy][Ee][Ss]) cmp -s ${ctrl_log}.yesterday ${ctrl_log}.today raid_rc=$? if test $raid_rc -ne 0; then diff -u ${ctrl_log}.yesterday ${ctrl_log}.today | \ grep -v '^-\|^$' fi ;; *) # XXX we might consider clearing the logs here # ${megacli} -AdpEventLog -Clear -a${ctrl} raid_rc=0 lines=`wc -l ${ctrl_log}.today | awk '{ print $1 }'` if test $lines -gt 4; then cat ${ctrl_log}.today raid_rc=1 fi esac if test $raid_rc -eq 0; then echo " No new log messages." fi [ $rc -eq 0 ] && [ $raid_rc -ne 0 ] && rc=3 done exit ${rc} # end