Skip to content

Commit

Permalink
merge upstream changes for
Browse files Browse the repository at this point in the history
  • Loading branch information
nedjitef committed Oct 15, 2022
1 parent 1ae8261 commit 790e0e6
Showing 1 changed file with 65 additions and 82 deletions.
147 changes: 65 additions & 82 deletions agents/plugins/smart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/bash
# Copyright (C) 2019 tribe29 GmbH - License: GNU General Public License v2
# Copyright (C) 2021 inett GmbH - License: GNU General Public License v2
# This file contains parts of a copy of Checkmk (https://checkmk.com). It is subject to the terms and
# Copyright (C) 2022 inett GmbH - License: GNU General Public License v2
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
# conditions defined in the file COPYING, which is part of this source code package.

# Reason for this no-op: shellcheck disable=... before the first command disables the error for the
Expand All @@ -10,7 +10,7 @@

# Disable unused variable error (needed to keep track of version)
# shellcheck disable=SC2034
CMK_VERSION="2.0.0p4"
CMK_VERSION="2.2.0i1"

# Function to replace "if type [somecmd]" idiom
# 'command -v' tends to be more robust vs 'which' and 'type' based tests
Expand All @@ -21,75 +21,48 @@ inpath() {
# This will be called on LSI based raidcontrollers and accesses
# the SMART data of SATA disks attached to a SAS Raid HBA via
# SCSI protocol interface.
megaraid_info()
{
megaraid_info() {
#PDINFO=$(MegaCli -PDlist -a0)
if [ -z "$1" ]; then
PDINFO=$(megacli -PDlist -a0 -NoLog)
else
PDINFO=$($1 -PDlist -a0 -NoLog)
fi

echo "$PDINFO" | \
while read -r line ; do
case "$line" in
"Adapter #"*)
CTRL=$( echo "$line" | sed 's/^\(.*\)\#//' )
SG=$($1 -AdpGetPciInfo -a${CTRL} | while read -r p_line ; do
case "$p_line" in
*"Controller $CTRL")
continue
echo "$PDINFO" |
while read -r line; do
case "$line" in
# FIRST LINE
"Enclosure Device ID"*) #Enclosure Device ID: 252
ENC=$(echo "$line" | awk '{print $4}')
unset SLOT LOG_DEV_ID VEND MODEL
;;
"Bus Number "*)
PCI_BUS=$( echo "$p_line" | cut -d ':' -f 2 | xargs )
PCI_BUS=$( printf %02x $PCI_BUS )
"Slot Number"*) #Slot Number: 7
SLOT=$(echo "$line" | awk '{print $3}')
;;
"Device Number "*)
PCI_DEV=$( echo "$p_line" | cut -d ':' -f 2 | xargs )
PCI_DEV=$( printf %02x $PCI_DEV )
# Identify the logical device ID. smartctl needs it to access the disk.
"Device Id"*) #Device Id: 19
LOG_DEV_ID=$(echo "$line" | awk '{print $3}')
;;
"Function Number "*)
PCI_FUN=$( echo "$p_line" | cut -d ':' -f 2 | xargs )
PCI_FUN=$( printf %01x $PCI_FUN )
SG_PATH=( "/sys/bus/pci/devices/*:${PCI_BUS}:${PCI_DEV}.${PCI_FUN}/host*/target*/*/scsi_generic/sg*" )
basename $( echo $SG_PATH | cut -d ' ' -f 1 )
exit
"PD Type"*) #PD Type: SATA
VEND=$(echo "$line" | awk '{print $3}')
;;
esac
done)
;;
# FIRST LINE
"Enclosure Device ID"*) #Enclosure Device ID: 252
ENC=$( echo "$line" | awk '{print $4}')
unset SLOT LOG_DEV_ID VEND MODEL
;;
"Slot Number"*) #Slot Number: 7
SLOT=$( echo "$line" | awk '{print $3}')
;;
# Identify the logical device ID. smartctl needs it to access the disk.
"Device Id"*) #Device Id: 19
LOG_DEV_ID=$( echo "$line" | awk '{print $3}')
;;
"PD Type"*) #PD Type: SATA
VEND=$( echo "$line" | awk '{print $3}')
;;
# This is the last value, generate output here
"Inquiry Data"*)
#Inquiry Data: WD-WCC1T1035197WDC WD20EZRX-00DC0B0 80.00A80
# $4 seems to be better for some vendors... wont be possible to get this perfect.
MODEL=$( echo "$line" | awk '{print $3}')
# This is the last value, generate output here
"Inquiry Data"*)
#Inquiry Data: WD-WCC1T1035197WDC WD20EZRX-00DC0B0 80.00A80
# $4 seems to be better for some vendors... wont be possible to get this perfect.
MODEL=$(echo "$line" | awk '{print $3}')

# /dev/sdc ATA SAMSUNG_SSD_830 5 Reallocated_Sector_Ct 0x0033 100 100 010 Pre-fail Always -
smartctl -d megaraid,"${LOG_DEV_ID}" -v 9,raw48 -A /dev/${SG} | \
grep Always | grep -E -v '^190(.*)Temperature(.*)' | \
sed "s|^|Con${CTRL}/Enc${ENC}/Slot${SLOT} $VEND $MODEL |"
;;
# /dev/sdc ATA SAMSUNG_SSD_830 5 Reallocated_Sector_Ct 0x0033 100 100 010 Pre-fail Always -
smartctl -d megaraid,"${LOG_DEV_ID}" -v 9,raw48 -A /dev/sg0 |
grep Always | grep -v -E '^190(.*)Temperature(.*)' |
sed "s|^|Enc${ENC}/Slot${SLOT} $VEND $MODEL |"
;;
esac
done
done
}

storcli_info()
{
storcli_info() {
$1 /call show all | while read -r line; do
case "$line" in
"Controller = "*)
Expand Down Expand Up @@ -198,20 +171,20 @@ storcli_info()
}

# Only handle always updated values, add device path and vendor/model
if which smartctl > /dev/null 2>&1 ; then
if inpath smartctl >/dev/null 2>&1; then
#
# if the 3ware-utility is found
# get the serials for all disks on the controller
#
if which tw_cli > /dev/null 2>&1 ; then
if inpath tw_cli >/dev/null 2>&1; then
# support for only one controller at the moment
TWAC=$(tw_cli show | awk 'NR < 4 { next } { print $1 }' | head -n 1)

# - add a trailing zero to handle case of unused slot
# trailing zeros are part of the device links in /dev/disk/by-id/... anyway
# - only the last 9 chars seem to be relevant
# (hopefully all this doesn't change with new kernels...)
eval "$(tw_cli /"$TWAC" show drivestatus | grep -E '^p[0-9]' | awk '{print $1 " " $7 "0"}' | while read -r twaminor serial ; do
eval "$(tw_cli /"$TWAC" show drivestatus | grep -E '^p[0-9]' | awk '{print $1 " " $7 "0"}' | while read -r twaminor serial; do
twaminor=${twaminor#p}
serial=${serial:(-9)}
serial=AMCC_${serial}00000000000
Expand All @@ -225,23 +198,24 @@ if which smartctl > /dev/null 2>&1 ; then
echo '<<<smart>>>'
SEEN=
for D in /dev/disk/by-id/{scsi,ata,nvme}-*; do
# don't use brace expansion here to stay POSIX conform
for D in /dev/disk/by-id/scsi-* /dev/disk/by-id/ata-* /dev/disk/by-id/nvme-*; do
[ "$D" != "${D%scsi-\*}" ] && continue
[ "$D" != "${D%ata-\*}" ] && continue
[ "$D" != "${D%nvme-\*}" ] && continue
[ "$D" != "${D%-part*}" ] && continue
N=$(readlink "$D")
N=${N##*/}
if [ -r /sys/block/"$N"/device/vendor ]; then
VEND=$(tr -d ' ' < /sys/block/"$N"/device/vendor)
VEND=$(tr -d ' ' </sys/block/"$N"/device/vendor)
elif [ -r /sys/block/"$N"/device/device/vendor ]; then
VEND=NVME
else
# 2012-01-25 Stefan Kaerst CDJ - in case $N does not exist
VEND=ATA
fi
if [ -r /sys/block/"$N"/device/model ]; then
MODEL=$(sed -e 's/ /_/g' -e 's/_*$//g' < /sys/block/"$N"/device/model)
MODEL=$(sed -e 's/ /_/g' -e 's/_*$//g' </sys/block/"$N"/device/model)
else
MODEL=$(smartctl -a "$D" | grep -i "device model" | sed -e "s/.*:[ ]*//g" -e "s/\ /_/g")
fi
Expand All @@ -256,7 +230,7 @@ if which smartctl > /dev/null 2>&1 ; then
fi
# Avoid duplicate entries for same device
if [ "${SEEN//.$N./}" != "$SEEN" ] ; then
if [ "${SEEN//.$N./}" != "$SEEN" ]; then
continue
fi
SEEN="$SEEN.$N."
Expand All @@ -276,15 +250,15 @@ if which smartctl > /dev/null 2>&1 ; then
MODEL=${MODEL// /-}
DNAME=${DNAME#AMCC_}
DNAME="AMCC_${MODEL}_${DNAME%000000000000}"
elif [ "$VEND" != "ATA" ] ; then
if [ "$VEND" == "NVME" ] ; then
elif [ "$VEND" != "ATA" ]; then
if [ "$VEND" == "NVME" ]; then
DNAME="/dev/$N"
CMD="smartctl -d nvme -A $DNAME"
else
TEMP=
# create temperature output as expected by checks/smart
# this is a hack, TODO: change checks/smart to support SCSI-disks
eval "$(smartctl -d scsi -i -A "$D" | while read -r a b c d _ ; do
eval "$(smartctl -d scsi -i -A "$D" | while read -r a b c d _; do
[ "$a" == Serial ] && echo SN="$c"
[ "$a" == Current ] && [ "$b" == Drive ] && [ "$c" == Temperature: ] && echo TEMP="$d"
done)"
Expand All @@ -295,30 +269,39 @@ if which smartctl > /dev/null 2>&1 ; then
CMD="smartctl -d ata -v 9,raw48 -A $D"
fi
if [ $VEND == "NVME" ]; then
echo "$DNAME $VEND $MODEL"
[ -n "$CMD" ] && $CMD | sed -e '1,5d; /^$/d'
else
[ -n "$CMD" ] && $CMD | grep Always | grep -E -v '^190(.*)Temperature(.*)' | sed "s|^|$DNAME $VEND $MODEL |"
fi
if [ $VEND == "NVME" ]; then
echo "$DNAME $VEND $MODEL"
[ -n "$CMD" ] && $CMD | sed -e '1,5d; /^$/d'
else
[ -n "$CMD" ] && $CMD | grep Always | grep -v -E '^190(.*)Temperature(.*)' | sed "s|^|$DNAME $VEND $MODEL |"
fi
done 2>/dev/null
# Call storcli if available
if inpath storcli; then
storcli_info storcli
StorCli_bin="storcli"
elif inpath storcli64; then
storcli_info storcli64
StorCli_bin="storcli64"
else
StorCli_bin="unknown"
fi
# Call MegaRaid submodule if conditions are met
elif inpath MegaCli; then
megaraid_info MegaCli
elif inpath MegaCli64; then
megaraid_info MegaCli64
elif inpath megacli; then
megaraid_info megacli
if type MegaCli >/dev/null 2>&1; then
MegaCli_bin="MegaCli"
elif type MegaCli64 >/dev/null 2>&1; then
MegaCli_bin="MegaCli64"
elif type megacli >/dev/null 2>&1; then
MegaCli_bin="megacli"
else
MegaCli_bin="unknown"
fi
if [ "$StorCli_bin" != "unknown" ]; then
storcli_info "$StorCli_bin"
elif [ "$MegaCli_bin" != "unknown" ]; then
megaraid_info "$MegaCli_bin"
fi
else
echo "ERROR: smartctl not found" >&2
fi

0 comments on commit 790e0e6

Please sign in to comment.