From 8ba42e8828f8d73ce50ed5a0381d2ba6b90d4b62 Mon Sep 17 00:00:00 2001 From: TechHome Date: Fri, 3 Jul 2020 15:44:29 +0200 Subject: [PATCH] Added SAS compatibility and other improvements (#13) * Added SAS compatibility and other improvements Added SAS compatibility and other improvements * Update smart_report.sh * Update smart_report.sh * Replaced egrep to grep -E - egrep is depreaced --- smart_report.sh | 211 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 157 insertions(+), 54 deletions(-) diff --git a/smart_report.sh b/smart_report.sh index 9e72f4d..117b75b 100644 --- a/smart_report.sh +++ b/smart_report.sh @@ -30,14 +30,15 @@ critSymbol="!" #if [ "$("${"$smartctl"}" -i /dev/${drive} | grep "SMART support is: Enabled" | awk '{print $3}')" ] #then printf ${drive}" "; fi done | awk '{for (i=NF; i!=0 ; i--) print $i }') -# 3. A "$smartctl"-based function: +# 3. "$smartctl"-based functions: + get_smart_drives() { gs_smartdrives="" gs_drives=$("$smartctl" --scan | awk '{print $1}') for gs_drive in $gs_drives; do - gs_smart_flag=$("$smartctl" -i "$gs_drive" | egrep "SMART support is:[[:blank:]]+Enabled" | awk '{print $4}') + gs_smart_flag=$("$smartctl" -i "$gs_drive" | grep -E "SMART support is:[[:blank:]]+Enabled" | awk '{print $4}') if [ "$gs_smart_flag" = "Enabled" ]; then gs_smartdrives="$gs_smartdrives $gs_drive" fi @@ -48,8 +49,45 @@ get_smart_drives() drives=$(get_smart_drives) + +# Checks whether it is a SATA disk +get_sata_drives() +{ + gsata_smartdrives="" + + for drive in $drives; do + gsata_smart_flag=$("$smartctl" -i "$drive" | grep -E "SATA Version is:[[:blank:]]" | awk '{print $4}') + if [ "$gsata_smart_flag" = "SATA" ]; then + gsata_smartdrives="$gsata_smartdrives $drive" + fi + done + + echo "$gsata_smartdrives" +} + +satadrives=$(get_sata_drives) + + +# Checks whether it is a SAS disk +get_sas_drives() +{ + gsas_smartdrives="" + + for drive in $drives; do + gsas_smart_flag=$("$smartctl" -i "$drive" | grep -E "Transport protocol:[[:blank:]]+SAS" | awk '{print $3}') + if [ "$gsas_smart_flag" = "SAS" ]; then + gsas_smartdrives="$gsas_smartdrives $drive" + fi + done + + echo "$gsas_smartdrives" +} + +sasdrives=$(get_sas_drives) + # end of method 3. + ### Set email headers ### printf "%s\n" "To: ${email} Subject: ${subject} @@ -62,18 +100,20 @@ Content-Transfer-Encoding: 7bit Content-Disposition: inline
" > ${logfile}
 
-###### summary ######
+
+###### summary sata ######
 (
- echo "########## SMART status report summary for all drives on server ${freenashost} ##########"
- echo ""
- echo "+------+------------------------+----+-----+-----+-----+-------+-------+--------+------+----------+------+-------+----+"
- echo "|Device|Serial                  |Temp|Power|Start|Spin |ReAlloc|Current|Offline |Seek  |Total     |High  |Command|Last|"
- echo "|      |Number                  |    |On   |Stop |Retry|Sectors|Pending|Uncorrec|Errors|Seeks     |Fly   |Timeout|Test|"
- echo "|      |                        |    |Hours|Count|Count|       |Sectors|Sectors |      |          |Writes|Count  |Age |"
- echo "+------+------------------------+----+-----+-----+-----+-------+-------+--------+------+----------+------+-------+----+"
+  echo "########## SMART status report summary for all SATA drives on server ${freenashost} ##########"
+  echo ""
+  echo "+------+------------------------+----+-----+-----+-----+-------+-------+--------+------+----------+------+--------------+-----+"
+  echo "|Device|Serial                  |Temp|Power|Start|Spin |ReAlloc|Current|Offline |Seek  |Total     |High  |Command       |Last |"
+  echo "|      |Number                  |    |On   |Stop |Retry|Sectors|Pending|Uncorrec|Errors|Seeks     |Fly   |Timeout       |Test |"
+  echo "|      |                        |    |Hours|Count|Count|       |Sectors|Sectors |      |          |Writes|Count         |Age  |"
+  echo "+------+------------------------+----+-----+-----+-----+-------+-------+--------+------+----------+------+--------------+-----+"
 ) >> "$logfile"
 
-for drive in $drives; do
+###### for each SATA drive ######
+for drive in $satadrives; do
   (
   devid=$(basename "$drive")
   lastTestHours=$("$smartctl" -l selftest "$drive" | grep "# 1" | awk '{print $9}')
@@ -94,57 +134,120 @@ for drive in $drives; do
   /High_Fly_Writes/{hiFlyWr=$10}
   /Command_Timeout/{cmdTimeout=$10}
   END {
-      testAge=sprintf("%.0f", (onHours - lastTestHours) / 24);
-      if (temp > tempCrit || reAlloc > sectorsCrit || pending > sectorsCrit || offlineUnc > sectorsCrit)
-          device=device " " critSymbol;
-      else if (temp > tempWarn || reAlloc > 0 || pending > 0 || offlineUnc > 0 || testAge > testAgeWarn)
-          device=device " " warnSymbol;
-      seekErrors=sprintf("%d", seekErrors);
-      totalSeeks=sprintf("%d", totalSeeks);
-      if (totalSeeks == "0") {
-          seekErrors="N/A";
-          totalSeeks="N/A";
-      }
-      if (temp > tempWarn || temp > tempCrit)
-         temp=temp"*"
-      else
-         temp=temp" "
+    testAge=sprintf("%.0f", (onHours - lastTestHours) / 24);
+    if (temp > tempCrit || reAlloc > sectorsCrit || pending > sectorsCrit || offlineUnc > sectorsCrit)
+      device=device " " critSymbol;
+    else if (temp > tempWarn || reAlloc > 0 || pending > 0 || offlineUnc > 0 || testAge > testAgeWarn)
+      device=device " " warnSymbol;
+    seekErrors=sprintf("%d", seekErrors);
+    totalSeeks=sprintf("%d", totalSeeks);
+    if (totalSeeks == "0") {
+      seekErrors="N/A";
+      totalSeeks="N/A";
+    }
+    if (temp > tempWarn || temp > tempCrit)
+       temp=temp"*"
+    else
+       temp=temp" "
 
-      if (reAlloc > 0 || reAlloc > sectorsCrit)
-         reAlloc=reAlloc"*"
-      
-      if (pending > 0 || pending > sectorsCrit)
-         pending=pending"*"
+    if (reAlloc > 0 || reAlloc > sectorsCrit)
+       reAlloc=reAlloc"*"
+    
+    if (pending > 0 || pending > sectorsCrit)
+       pending=pending"*"
 
-      if (offlineUnc > 0 || offlineUnc > sectorsCrit)
-         offlineUnc=offlineUnc"*"
+    if (offlineUnc > 0 || offlineUnc > sectorsCrit)
+       offlineUnc=offlineUnc"*"
 
-      if (testAge > testAgeWarn)
-         testAge=testAge"*"
-      
-      if (hiFlyWr == "") hiFlyWr="N/A";
-      if (cmdTimeout == "") cmdTimeout="N/A";
-      printf "|%-6s|%-24s| %3s|%5s|%5s|%5s|%7s|%7s|%8s|%6s|%10s|%6s|%7s|%4s|\n",
-      device, serial, temp, onHours, startStop, spinRetry, reAlloc, pending, offlineUnc,
-      seekErrors, totalSeeks, hiFlyWr, cmdTimeout, testAge;
-      }'
+    if (testAge > testAgeWarn)
+       testAge=testAge"*"
+
+    if (hiFlyWr == "") hiFlyWr="N/A";
+    if (cmdTimeout == "") cmdTimeout="N/A";
+    printf "|%-6s|%-24s| %3s|%5s|%5s|%5s|%7s|%7s|%8s|%6s|%10s|%6s|%14s|%5s|\n",
+    device, serial, temp, onHours, startStop, spinRetry, reAlloc, pending, offlineUnc,
+    seekErrors, totalSeeks, hiFlyWr, cmdTimeout, testAge;
+    }'
+  ) >> "$logfile"
+done
+(
+  echo "+------+------------------------+----+-----+-----+-----+-------+-------+--------+------+----------+------+--------------+-----+"
+) >> "$logfile"
+
+(
+  echo ""
+  echo ""
+  echo ""
+) >> "$logfile"
+
+
+###### summary sas ######
+(
+  echo ""
+  echo "########## SMART status report summary for all SAS drives on server ${freenashost} ##########"
+  echo ""
+  echo "+------+------------------------+----+-----+------+------+------+------+------+------+"
+  echo "|Device|Serial                  |Temp|Start|Load  |Defect|Uncorr|Uncorr|Uncorr|Non   |"
+  echo "|      |Number                  |    |Stop |Unload|List  |Read  |Write |Verify|Medium|"
+  echo "|      |                        |    |Count|Count |Elems |Errors|Errors|Errors|Errors|"
+  echo "+------+------------------------+----+-----+------+------+------+------+------+------+"
+) >> "$logfile"
+
+###### for each SAS drive ######
+for drive in $sasdrives; do
+  (
+  devid=$(basename "$drive")
+  "$smartctl" -a "$drive" | \
+  awk -v device="$devid" -v tempWarn="$tempWarn" -v tempCrit="$tempCrit" \
+  -v warnSymbol="$warnSymbol" -v critSymbol="$critSymbol" '\
+  /Serial number:/{serial=$3}
+  /Current Drive Temperature:/{temp=$4} \
+  /start-stop cycles:/{startStop=$4} \
+  /load-unload cycles:/{loadUnload=$4} \
+  /grown defect list:/{defectList=$6} \
+  /read:/{readErrors=$8} \
+  /write:/{writeErrors=$8} \
+  /verify:/{verifyErrors=$8} \
+  /Non-medium error count:/{nonMediumErrors=$4} \
+  END {
+    if (temp > tempCrit)
+	  device=device " " critSymbol;
+	else if (temp > tempWarn)
+      device=device " " warnSymbol;
+	  printf "|%-6s|%-24s| %3s|%5s|%6s|%6s|%6s|%6s|%6s|%6s|\n",
+	  device, serial, temp, startStop, loadUnload, defectList, \
+	  readErrors, writeErrors, verifyErrors, nonMediumErrors;
+   }'
+  ) >> "$logfile"
+done
+(
+  echo "+------+------------------------+----+-----+------+------+------+------+------+------+"
+) >> "$logfile"
+
+
+###### for SATA drives ######
+for drive in $satadrives; do
+  brand=$("$smartctl" -i "$drive" | grep "Model Family" | sed "s/^.*   //")
+  if [ -z "$brand" ]; then
+    brand=$("$smartctl" -i "$drive" | grep "Device Model" | sed "s/^.* //")
+  fi
+  serial=$("$smartctl" -i "$drive" | grep "Serial Number" | sed "s/^.* //")
+  (
+  echo ""
+  echo "########## SMART status report for $drive drive (${brand} : ${serial}) ##########"
+  "$smartctl" -n never -H -A -l error "$drive"
+  "$smartctl" -n never -l selftest "$drive" | grep "# 1 \\|Num" | cut -c6-
   ) >> "$logfile"
 done
 
-(
-  echo "+------+------------------------+----+-----+-----+-----+-------+-------+--------+------+----------+------+-------+----+"
-) >> "$logfile"
-
-###### for each drive ######
-for drive in $drives; do
-  brand=$("$smartctl" -i "$drive" | grep "Model Family" | awk '{print $3, $4, $5, $6, $7}')
-  if [ -z "$brand" ]; then
-    brand=$("$smartctl" -i "$drive" | grep "Device Model" | awk '{print $3, $4, $5, $6, $7}')
-  fi
-  serial=$("$smartctl" -i "$drive" | grep "Serial Number" | awk '{print $3}')
+###### for SAS drives ######
+for drive in $sasdrives; do
+  devid=$(basename "$drive")
+  brand=$("$smartctl" -i "$drive" | grep "Product" | sed "s/^.* //")
+  serial=$("$smartctl" -i "$drive" | grep "Serial number" | sed "s/^.* //")
   (
   echo ""
-  echo "########## SMART status report for $drive drive (${brand}: ${serial}) ##########"
+  echo "########## SMART status report for $drive drive (${brand} : ${serial}) ##########"
   "$smartctl" -n never -H -A -l error "$drive"
   "$smartctl" -n never -l selftest "$drive" | grep "# 1 \\|Num" | cut -c6-
   ) >> "$logfile"