diff --git a/checkmk/checkmk-files/smart b/checkmk/checkmk-files/smart
index 6e28c91faf990e511e00ab7b98081c9512719aa9..d0636ca191a930404c5cb1c5319caa9a26a3ff18 100644
--- a/checkmk/checkmk-files/smart
+++ b/checkmk/checkmk-files/smart
@@ -1,30 +1,21 @@
#!/bin/bash
-# +------------------------------------------------------------------+
-# | ____ _ _ __ __ _ __ |
-# | / ___| |__ ___ ___| | __ | \/ | |/ / |
-# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
-# | | |___| | | | __/ (__| < | | | | . \ |
-# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
-# | |
-# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
-# +------------------------------------------------------------------+
-#
-# This file is part of Check_MK.
-# The official homepage is at http://mathias-kettner.de/check_mk.
-#
-# check_mk is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation in version 2. check_mk is distributed
-# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
-# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE. See the GNU General Public License for more de-
-# tails. You should have received a copy of the GNU General Public
-# License along with GNU Make; see the file COPYING. If not, write
-# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
-# Boston, MA 02110-1301 USA.
-
-
-
+# Copyright (C) 2019 tribe29 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
+# entire script.
+:
+
+# Disable unused variable error (needed to keep track of version)
+# shellcheck disable=SC2034
+CMK_VERSION="2.0.0p12"
+
+# Function to replace "if type [somecmd]" idiom
+# 'command -v' tends to be more robust vs 'which' and 'type' based tests
+inpath() {
+ command -v "${1:?No command to test}" >/dev/null 2>&1
+}
# This will be called on LSI based raidcontrollers and accesses
# the SMART data of SATA disks attached to a SAS Raid HBA via
@@ -39,7 +30,7 @@ megaraid_info()
fi
echo "$PDINFO" | \
- while read line ; do
+ while read -r line ; do
case "$line" in
# FIRST LINE
"Enclosure Device ID"*) #Enclosure Device ID: 252
@@ -63,8 +54,8 @@ megaraid_info()
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/sg0 | \
- grep Always | egrep -v '^190(.*)Temperature(.*)' | \
+ smartctl -d megaraid,"${LOG_DEV_ID}" -v 9,raw48 -A /dev/sg0 | \
+ grep Always | grep -E -v '^190(.*)Temperature(.*)' | \
sed "s|^|Enc${ENC}/Slot${SLOT} $VEND $MODEL |"
;;
esac
@@ -86,37 +77,47 @@ if which smartctl > /dev/null 2>&1 ; then
# 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 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
echo "$serial=$twaminor"
- done`
- else:
+ done)"
+ else
echo "tw_cli not found" >&2
fi
+ INPATH_UDEVADM=$(inpath udevadm && echo "udevadm_present")
+
echo '<<<smart>>>'
SEEN=
- for D in /dev/disk/by-id/{scsi,ata}-*; do
+ for D in /dev/disk/by-id/{scsi,ata,nvme}-*; do
[ "$D" != "${D%scsi-\*}" ] && continue
[ "$D" != "${D%ata-\*}" ] && continue
+ [ "$D" != "${D%nvme-\*}" ] && continue
[ "$D" != "${D%-part*}" ] && continue
- N=$(readlink $D)
+ N=$(readlink "$D")
N=${N##*/}
- if [ -r /sys/block/$N/device/vendor ]; then
- VEND=$(tr -d ' ' < /sys/block/$N/device/vendor)
+ if [ -r /sys/block/"$N"/device/vendor ]; then
+ 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)
+ if [ -r /sys/block/"$N"/device/model ]; then
+ 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")
+ MODEL=$(smartctl -a "$D" | grep -i "device model" | sed -e "s/.*:[ ]*//g" -e "s/\ /_/g")
fi
# Excluded disk models for SAN arrays or certain RAID luns that are also not usable..
- if [ "$MODEL" = "iSCSI_Disk" -o "$MODEL" = "LOGICAL_VOLUME" ]; then
+ if [ "$MODEL" = "iSCSI_Disk" ] || [ "$MODEL" = "LOGICAL_VOLUME" ]; then
+ continue
+ fi
+
+ # Exclude everything which can read a CD
+ if [ "$INPATH_UDEVADM" == "udevadm_present" ] && (udevadm info /dev/"$N" | grep -Fxq 'E: ID_CDROM_CD=1'); then
continue
fi
@@ -131,31 +132,41 @@ if which smartctl > /dev/null 2>&1 ; then
DNAME=${DNAME#/dev/disk/by-id/ata-}
# 2012-01-25 Stefan Kaerst CDJ - special option in case vendor is AMCC
CMD=
- if [ "$VEND" == "AMCC" -a -n "$TWAC" ]; then
+ if [ "$VEND" == "AMCC" ] && [ -n "$TWAC" ]; then
DNAME=${DNAME#1}
[ -z "${!DNAME}" ] && continue
CMD="smartctl -d 3ware,${!DNAME} -v 9,raw48 -A /dev/twa0"
# create nice device name including model
- MODEL=$(tw_cli /$TWAC/p${!DNAME} show model | head -n 1 | awk -F= '{ print $2 }')
+ MODEL=$(tw_cli /"$TWAC"/p"${!DNAME}" show model | head -n 1 | awk -F= '{ print $2 }')
MODEL=${MODEL## }
MODEL=${MODEL// /-}
DNAME=${DNAME#AMCC_}
DNAME="AMCC_${MODEL}_${DNAME%000000000000}"
elif [ "$VEND" != "ATA" ] ; then
- 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 a b c d e ; do
- [ "$a" == Serial ] && echo SN=$c
- [ "$a" == Current -a "$b" == Drive -a "$c" == Temperature: ] && echo TEMP=$d
- done`
- [ -n "$TEMP" ] && CMD="echo 194 Temperature_Celsius 0x0000 000 000 000 Old_age Always - $TEMP (0 0 0 0)"
- DNAME="${VEND}_${MODEL}_${SN}"
+ 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
+ [ "$a" == Serial ] && echo SN="$c"
+ [ "$a" == Current ] && [ "$b" == Drive ] && [ "$c" == Temperature: ] && echo TEMP="$d"
+ done)"
+ [ -n "$TEMP" ] && CMD="echo 194 Temperature_Celsius 0x0000 000 000 000 Old_age Always - $TEMP (0 0 0 0)"
+ DNAME="${VEND}_${MODEL}_${SN}"
+ fi
else
CMD="smartctl -d ata -v 9,raw48 -A $D"
fi
- [ -n "$CMD" ] && $CMD | grep Always | egrep -v '^190(.*)Temperature(.*)' | sed "s|^|$DNAME $VEND $MODEL |"
+ 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
done 2>/dev/null