Advertisement
Guest User

Untitled

a guest
May 17th, 2017
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 15.52 KB | None | 0 0
  1. #!/bin/bash
  2.  
  3. ###### Parameters ######
  4. logfile="/tmp/smart_report.tmp"
  5. email="email address"
  6. subject="Status report"
  7. drives="da0 da1 da2 da3 da4 da5 da6 da7 da8 da9 da10 da11 da12 da13 da14 da15"
  8. pools="freenas-boot tank"
  9. tempWarn=40
  10. tempCrit=45
  11. sectorsCrit=10
  12. testAgeWarn=5
  13. usedWarn=90
  14. scrubAgeWarn=30
  15. warnColor="#ffd6d6"
  16. critColor="#ff0000"
  17. altColor="#f4f4f4"
  18. warnSymbol="?"
  19. critSymbol="!"
  20.  
  21. ### Config Backup Parameters ###
  22. config_logfile="/tmp/config_backup_error.tmp"
  23. tarfile="/tmp/config_backup.tar"
  24. filename="$(date "+FreeNAS_Config_%Y-%m-%d_%H-%M-%S")"
  25. config_subject="Config backup"
  26.  
  27. ###### Pre-formatting ######
  28. ### Set email headers ###
  29. (
  30.         echo "To: ${email}"
  31.         echo "Subject: ${subject}"
  32.         echo "Content-Type: text/html"
  33.         echo "MIME-Version: 1.0"
  34.         echo -e "\r\n"
  35.         echo "<div>"
  36. ) > "$logfile"
  37.  
  38. ### Check config integrity ###
  39. if ! [ "$(sqlite3 /data/freenas-v1.db "pragma integrity_check;")" == "ok" ]; then
  40.     (
  41.         echo "<b>Automatic backup of FreeNAS config failed! The config file is corrupted!</b>"
  42.         echo "<b>You should correct this problem as soon as possible!</b>"
  43.     ) >> "$logfile"
  44. fi
  45.  
  46. ###### Report Summary Section (html tables) ######
  47. ### zpool status summary table ###
  48. (
  49.     echo "<br><br>"
  50.     echo "<table style=\"border: 1px solid black; border-collapse: collapse;\">"
  51.     echo "<tr><th colspan=\"9\" style=\"text-align:center; font-size:20px; height:40px; font-family:courier;\">ZPool Status Report Summary (All Pools)</th></tr>"
  52.     echo "<tr>"
  53.     echo "  <th style=\"text-align:center; width:130px; height:60px; border:1px solid black; border-collapse:collapse; font-family:courier;\">Pool<br>Name</th>"
  54.     echo "  <th style=\"text-align:center; width:130px; height:60px; border:1px solid black; border-collapse:collapse; font-family:courier;\">Status</th>"
  55.     echo "  <th style=\"text-align:center; width:130px; height:60px; border:1px solid black; border-collapse:collapse; font-family:courier;\">Read<br>Errors</th>"
  56.     echo "  <th style=\"text-align:center; width:130px; height:60px; border:1px solid black; border-collapse:collapse; font-family:courier;\">Write<br>Errors</th>"
  57.     echo "  <th style=\"text-align:center; width:130px; height:60px; border:1px solid black; border-collapse:collapse; font-family:courier;\">Cksum<br>Errors</th>"
  58.     echo "  <th style=\"text-align:center; width:130px; height:60px; border:1px solid black; border-collapse:collapse; font-family:courier;\">Used %</th>"
  59.     echo "  <th style=\"text-align:center; width:130px; height:60px; border:1px solid black; border-collapse:collapse; font-family:courier;\">Scrub<br>Repaired<br>Bytes</th>"
  60.     echo "  <th style=\"text-align:center; width:130px; height:60px; border:1px solid black; border-collapse:collapse; font-family:courier;\">Scrub<br>Errors</th>"
  61.     echo "  <th style=\"text-align:center; width:130px; height:60px; border:1px solid black; border-collapse:collapse; font-family:courier;\">Last<br>Scrub<br>Age</th>"
  62.     echo "</tr>"
  63. ) >> "$logfile"
  64. poolNum=0
  65. for pool in $pools; do
  66.     status="$(zpool list -H -o health "$pool")"
  67.     errors="$(zpool status "$pool" | egrep "(ONLINE|DEGRADED|FAULTED|UNAVAIL|REMOVED)[ \t]+[0-9]+")"
  68.     readErrors=0
  69.     for err in $(echo "$errors" | awk '{print $3}'); do
  70.         if echo "$err" | egrep -q "[^0-9]+"; then
  71.             readErrors=1000
  72.             break
  73.         fi
  74.         readErrors=$((readErrors + err))
  75.     done
  76.     writeErrors=0
  77.     for err in $(echo "$errors" | awk '{print $4}'); do
  78.         if echo "$err" | egrep -q "[^0-9]+"; then
  79.             writeErrors=1000
  80.             break
  81.         fi
  82.         writeErrors=$((writeErrors + err))
  83.     done
  84.     cksumErrors=0
  85.     for err in $(echo "$errors" | awk '{print $5}'); do
  86.         if echo "$err" | egrep -q "[^0-9]+"; then
  87.             cksumErrors=1000
  88.             break
  89.         fi
  90.         cksumErrors=$((cksumErrors + err))
  91.     done
  92.     if [ "$readErrors" -gt 999 ]; then readErrors=">1K"; fi
  93.     if [ "$writeErrors" -gt 999 ]; then writeErrors=">1K"; fi
  94.     if [ "$cksumErrors" -gt 999 ]; then cksumErrors=">1K"; fi
  95.     used="$(zpool list -H -p -o capacity "$pool")"
  96.     scrubRepBytes="N/A"
  97.     scrubErrors="N/A"
  98.     scrubAge="N/A"
  99.     if [ "$(zpool status "$pool" | grep "scan" | awk '{print $2}')" = "scrub" ]; then
  100.         scrubRepBytes="$(zpool status "$pool" | grep "scan" | awk '{print $4}')"
  101.         scrubErrors="$(zpool status "$pool" | grep "scan" | awk '{print $8}')"
  102.         scrubDate="$(zpool status "$pool" | grep "scan" | awk '{print $15"-"$12"-"$13"_"$14}')"
  103.         scrubTS="$(date -j -f "%Y-%b-%e_%H:%M:%S" "$scrubDate" "+%s")"
  104.         currentTS="$(date "+%s")"
  105.         scrubAge=$((((currentTS - scrubTS) + 43200) / 86400))
  106.     fi
  107.     if [ $((poolNum % 2)) == 1 ]; then bgColor="#ffffff"; else bgColor="$altColor"; fi
  108.     poolNum=$((poolNum + 1))
  109.     if [ "$status" != "ONLINE" ]; then statusColor="#ffd6d6"; else statusColor="$bgColor"; fi
  110.     if [ "$readErrors" != "0" ]; then readErrorsColor="#ffd6d6"; else readErrorsColor="$bgColor"; fi
  111.     if [ "$writeErrors" != "0" ]; then writeErrorsColor="#ffd6d6"; else writeErrorsColor="$bgColor"; fi
  112.     if [ "$cksumErrors" != "0" ]; then cksumErrorsColor="#ffd6d6"; else cksumErrorsColor="$bgColor"; fi
  113.     if [ "$used" -gt "$usedWarn" ]; then usedColor="#ffd6d6"; else usedColor="$bgColor"; fi
  114.     if ( [ "$scrubRepBytes" != "N/A" ] && [ "$scrubRepBytes" != "0" ] ); then scrubRepBytesColor="#ffd6d6"; else scrubRepBytesColor="$bgColor"; fi
  115.     if ( [ "$scrubErrors" != "N/A" ] && [ "$scrubErrors" != "0" ] ); then scrubErrorsColor="#ffd6d6"; else scrubErrorsColor="$bgColor"; fi
  116.     if [ "$(echo "$scrubAge" | awk '{print int($1)}')" -gt "$scrubAgeWarn" ]; then scrubAgeColor="#ffd6d6"; else scrubAgeColor="$bgColor"; fi
  117.     (
  118.         printf "<tr style=\"background-color:%s;\">
  119.             <td style=\"text-align:center; font-size:85%%; height:25px; border:1px solid black; border-collapse:collapse; font-family:courier;\">%s</td>
  120.             <td style=\"text-align:center; background-color:%s; font-size:85%%; height:25px; border:1px solid black; border-collapse:collapse; font-family:courier;\">%s</td>
  121.             <td style=\"text-align:center; background-color:%s; font-size:85%%; height:25px; border:1px solid black; border-collapse:collapse; font-family:courier;\">%s</td>
  122.             <td style=\"text-align:center; background-color:%s; font-size:85%%; height:25px; border:1px solid black; border-collapse:collapse; font-family:courier;\">%s</td>
  123.             <td style=\"text-align:center; background-color:%s; font-size:85%%; height:25px; border:1px solid black; border-collapse:collapse; font-family:courier;\">%s</td>
  124.             <td style=\"text-align:center; background-color:%s; font-size:85%%; height:25px; border:1px solid black; border-collapse:collapse; font-family:courier;\">%s%%</td>
  125.             <td style=\"text-align:center; background-color:%s; font-size:85%%; height:25px; border:1px solid black; border-collapse:collapse; font-family:courier;\">%s</td>
  126.             <td style=\"text-align:center; background-color:%s; font-size:85%%; height:25px; border:1px solid black; border-collapse:collapse; font-family:courier;\">%s</td>
  127.             <td style=\"text-align:center; background-color:%s; font-size:85%%; height:25px; border:1px solid black; border-collapse:collapse; font-family:courier;\">%s</td>
  128.         </tr>\n" "$bgColor" "$pool" "$statusColor" "$status" "$readErrorsColor" "$readErrors" "$writeErrorsColor" "$writeErrors" "$cksumErrorsColor" "$cksumErrors" "$usedColor" "$used" \
  129.         "$scrubRepBytesColor" "$scrubRepBytes" "$scrubErrorsColor" "$scrubErrors" "$scrubAgeColor" "$scrubAge"
  130.     ) >> "$logfile"
  131. done
  132. echo "</table>" >> "$logfile"
  133.  
  134. ### SMART status summary table ###
  135. (
  136.         echo "<br><br>"
  137.         echo "<table style=\"border: 1px solid black; border-collapse: collapse;\">"
  138.         echo "<tr><th colspan=\"12\" style=\"text-align:center; font-size:20px; height:40px; font-family:courier;\">SMART Status Report Summary (Pool Drives)</th></tr>"
  139.         echo "<tr>"
  140.         echo "  <th style=\"text-align:center; width:130px; height:60px; border:1px solid black; border-collapse:collapse; font-family:courier;\">Device</th>"
  141.         echo "  <th style=\"text-align:center; width:130px; height:60px; border:1px solid black; border-collapse:collapse; font-family:courier;\">Serial</th>"
  142.         echo "  <th style=\"text-align:center; width:130px; height:60px; border:1px solid black; border-collapse:collapse; font-family:courier;\">Temp</th>"
  143.         echo "  <th style=\"text-align:center; width:130px; height:60px; border:1px solid black; border-collapse:collapse; font-family:courier;\">Power On<br>Hours</th>"
  144.         echo "  <th style=\"text-align:center; width:130px; height:60px; border:1px solid black; border-collapse:collapse; font-family:courier;\">Start/Stop<br>Count</th>"
  145.         echo "  <th style=\"text-align:center; width:130px; height:60px; border:1px solid black; border-collapse:collapse; font-family:courier;\">Spin Retry<br>Count</th>"
  146.         echo "  <th style=\"text-align:center; width:130px; height:60px; border:1px solid black; border-collapse:collapse; font-family:courier;\">Reallocated<br>Sectors</th>"
  147.         echo "  <th style=\"text-align:center; width:130px; height:60px; border:1px solid black; border-collapse:collapse; font-family:courier;\">Current<br>Pending<br>Sectors</th>"
  148.         echo "  <th style=\"text-align:center; width:130px; height:60px; border:1px solid black; border-collapse:collapse; font-family:courier;\">Offline<br>Uncorrectable<br>Sectors</th>"
  149.         echo "  <th style=\"text-align:center; width:130px; height:60px; border:1px solid black; border-collapse:collapse; font-family:courier;\">UDMA/CRC<br>Errors</th>"
  150.         echo "  <th style=\"text-align:center; width:130px; height:60px; border:1px solid black; border-collapse:collapse; font-family:courier;\">Seek<br>Error<br>Rate</th>"
  151.         echo "  <th style=\"text-align:center; width:130px; height:60px; border:1px solid black; border-collapse:collapse; font-family:courier;\">Last Test<br>Age</th></tr>"
  152.         echo "</tr>"
  153. ) >> "$logfile"
  154. for drive in $drives; do
  155.     (
  156.         smartctl -A -i -v 7,hex48 /dev/"$drive" | \
  157.         awk -v device="$drive" -v tempWarn="$tempWarn" -v tempCrit="$tempCrit" -v sectorsCrit="$sectorsCrit" -v testAgeWarn="$testAgeWarn" -v warnColor="$warnColor" -v critColor="$critColor" -v altColor="$altColor" \
  158.         -v lastTestHours="$(smartctl -l selftest /dev/"$drive" | grep "# 1" | awk '{print $9}')" ' \
  159.         /Serial Number:/{serial=$3} \
  160.         /Temperature_Celsius/{temp=$10} \
  161.         /Power_On_Hours/{onHours=$10} \
  162.         /Start_Stop_Count/{startStop=$10} \
  163.         /Spin_Retry_Count/{spinRetry=$10} \
  164.         /Reallocated_Sector/{reAlloc=$10} \
  165.         /Current_Pending_Sector/{pending=$10} \
  166.         /Offline_Uncorrectable/{offlineUnc=$10} \
  167.         /UDMA_CRC_Error_Count/{crcErrors=$10} \
  168.         /Seek_Error_Rate/{seekErrors=sprintf("%d", "0x" substr($10,3,4))} \
  169.         END {
  170.             testAge=int((onHours - lastTestHours) / 24);
  171.             if ((substr(device,3) + 0) % 2 == 1) bgColor = "#ffffff"; else bgColor = "#f9f9f9";
  172.             if ((temp + 0) > tempCrit) tempColor = critColor; else if ((temp + 0) > tempWarn) tempColor = warnColor; else tempColor = bgColor;
  173.             if (spinRetry != "0") spinRetryColor = warnColor; else spinRetryColor = bgColor;
  174.             if ((reAlloc + 0) > sectorsCrit) reAllocColor = critColor; else if (reAlloc != 0) reAllocColor = warnColor; else reAllocColor = bgColor;
  175.             if ((pending + 0) > sectorsCrit) pendingColor = critColor; else if (pending != 0) pendingColor = warnColor; else pendingColor = bgColor;
  176.             if ((offlineUnc + 0) > sectorsCrit) offlineUncColor = critColor; else if (offlineUnc != 0) offlineUncColor = warnColor; else offlineUncColor = bgColor;
  177.             if (crcErrors != "0") crcErrorsColor = warnColor; else crcErrorsColor = bgColor;
  178.             if (seekErrors != "0") seekErrorsColor = warnColor; else seekErrorsColor = bgColor;
  179.             if (testAge > testAgeWarn) testAgeColor = warnColor; else testAgeColor = bgColor;
  180.  
  181.             printf "<tr style=\"background-color:%s;\">" \
  182.                 "<td style=\"text-align:center; font-size:85%%; height:25px; border:1px solid black; border-collapse:collapse; font-family:courier;\">%s</td>" \
  183.                 "<td style=\"text-align:center; font-size:85%%; height:25px; border:1px solid black; border-collapse:collapse; font-family:courier;\">%s</td>" \
  184.                 "<td style=\"text-align:center; background-color:%s; font-size:85%%; height:25px; border:1px solid black; border-collapse:collapse; font-family:courier;\">%s</td>" \
  185.                 "<td style=\"text-align:center; font-size:85%%; height:25px; border:1px solid black; border-collapse:collapse; font-family:courier;\">%s</td>" \
  186.                 "<td style=\"text-align:center; font-size:85%%; height:25px; border:1px solid black; border-collapse:collapse; font-family:courier;\">%s</td>" \
  187.                 "<td style=\"text-align:center; background-color:%s; font-size:85%%; height:25px; border:1px solid black; border-collapse:collapse; font-family:courier;\">%s</td>" \
  188.                 "<td style=\"text-align:center; background-color:%s; font-size:85%%; height:25px; border:1px solid black; border-collapse:collapse; font-family:courier;\">%s</td>" \
  189.                 "<td style=\"text-align:center; background-color:%s; font-size:85%%; height:25px; border:1px solid black; border-collapse:collapse; font-family:courier;\">%s</td>" \
  190.                 "<td style=\"text-align:center; background-color:%s; font-size:85%%; height:25px; border:1px solid black; border-collapse:collapse; font-family:courier;\">%s</td>" \
  191.                 "<td style=\"text-align:center; background-color:%s; font-size:85%%; height:25px; border:1px solid black; border-collapse:collapse; font-family:courier;\">%s</td>" \
  192.                 "<td style=\"text-align:center; background-color:%s; font-size:85%%; height:25px; border:1px solid black; border-collapse:collapse; font-family:courier;\">%s</td>" \
  193.                 "<td style=\"text-align:center; background-color:%s; font-size:85%%; height:25px; border:1px solid black; border-collapse:collapse; font-family:courier;\">%d</td>" \
  194.             "</tr>\n", bgColor, device, serial, tempColor, temp, onHours, startStop, spinRetryColor, spinRetry, reAllocColor, reAlloc, pendingColor, pending, offlineUncColor, offlineUnc, \
  195.             crcErrorsColor, crcErrors, seekErrorsColor, seekErrors, testAgeColor, testAge;
  196.         }'
  197.     ) >> "$logfile"
  198. done
  199. echo "</table>" >> "$logfile"
  200. echo "<br><br>" >> "$logfile"
  201. echo "</div>" >> "$logfile"
  202.  
  203. ###### Detailed Report Section (monospace text) ######
  204. echo "<pre style=\"font-size:14px\">" >> "$logfile"
  205.  
  206. ### zpool status for each pool ###
  207. for pool in $pools; do
  208.     (
  209.         echo ""
  210.         echo "<b>########## ZPool status report for ${pool} ##########</b>"
  211.         echo ""
  212.         zpool status -v "$pool"
  213.         echo ""
  214.         echo ""
  215.     ) >> "$logfile"
  216. done
  217.  
  218. ### SMART status for each drive ###
  219. for drive in $drives; do
  220.     brand="$(smartctl -i /dev/"$drive" | grep "Model Family" | awk '{print $3, $4, $5}')"
  221.     serial="$(smartctl -i /dev/"$drive" | grep "Serial Number" | awk '{print $3}')"
  222.     (
  223.         echo ""
  224.         echo "<b>########## SMART status report for ${drive} drive (${brand}: ${serial}) ##########</b>"
  225.         smartctl -H -A -l error /dev/"$drive"
  226.         smartctl -l selftest /dev/"$drive" | grep "# 1 \|Num" | cut -c6-
  227.         echo ""
  228.         echo ""
  229.     ) >> "$logfile"
  230. done
  231. sed -i '' -e '/smartctl 6.3/d' "$logfile"
  232. sed -i '' -e '/Copyright/d' "$logfile"
  233. sed -i '' -e '/=== START OF READ/d' "$logfile"
  234. sed -i '' -e '/SMART Attributes Data/d' "$logfile"
  235. sed -i '' -e '/Vendor Specific SMART/d' "$logfile"
  236. sed -i '' -e '/SMART Error Log Version/d' "$logfile"
  237.  
  238. ### End body ###
  239. echo "</pre>" >> "$logfile"
  240.  
  241.  
  242. ###### Send backup & report ######
  243. ### Send config backup ###
  244. if [ "$(sqlite3 /data/freenas-v1.db "pragma integrity_check;")" == "ok" ]; then
  245.     cp /data/freenas-v1.db "/tmp/${filename}.db"
  246.     md5 "/tmp/${filename}.db" > /tmp/config_backup.md5
  247.     sha256 "/tmp/${filename}.db" > /tmp/config_backup.sha256
  248.     cd "/tmp/"; tar -cf "${tarfile}" "./${filename}.db" ./config_backup.md5 ./config_backup.sha256; cd -
  249.     uuencode "${tarfile}" "${filename}.tar" | mail -s "${config_subject}" "${email}"
  250.     rm "/tmp/${filename}.db"
  251.     rm /tmp/config_backup.md5
  252.     rm /tmp/config_backup.sha256
  253.     rm "${tarfile}"
  254. fi
  255.  
  256. ### Send report ###
  257. sendmail -t < "$logfile"
  258. rm "$logfile"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement