SHARE
TWEET

armbian-monitoring

a guest Jan 19th, 2016 116 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/bin/bash
  2. #
  3. # armbian-monitoring
  4. #
  5. # This script is used to configure armbianmonitor behaviour.
  6. # It will ask the user whether to activate monitoring or not,
  7. # whether to enable debug monitoring and also how to deal with
  8. # connected disks. In fact it walks through the list of available
  9. # disks, checks them, tries to patch hddtemp.db if necessary
  10. # and provides a proposal for /etc/armbianmonitor/disks.conf
  11. # when a new disk is found.
  12. #
  13. # In case monitoring should be activated the following file
  14. # will be created: /etc/armbianmonitor/start-monitoring. If
  15. # debug output has been chosen, then DEBUG will be written to
  16. # the file.
  17. #
  18. # The script will install smartmontools/gdisk if not already
  19. # installed and patches smartmontools' update-smart-drivedb
  20. # script if necessary. For disks the 'device model' will be
  21. # shown but internally we rely always on the GUID. This is the
  22. # key for entry in /etc/armbianmonitor/disks.conf
  23. #
  24. # When the script exits and the user activated monitoring it
  25. # recommends doing a restart since on the next reboot the
  26. # setup-armbian-monitoring-environment script will configure
  27. # monitoring sources and decides based on the existence and
  28. # contents of /etc/armbianmonitor/start-monitoring whether
  29. # rpimonitord should be started or not.
  30. #
  31. # The format of /etc/armbianmonitor/disks.conf is as follows:
  32. #
  33. # ${GUID}:${smartctl prefix}:${temp call}:${CRC attribute}:${LCC attribute}
  34. #
  35. # Two examples:
  36. #
  37. # A57BF307-7D82-4783-BD1D-B346CA8C195B:::199:193 # WD HDD on SATA
  38. # F8D372DC-63DB-494B-B802-87DC47FAD4E1:sat::199: # SSD in USB enclosure
  39. #
  40. # - GUID is the GUID as determined by gdisk
  41. # - "smartctl prefix" can be empty or should be the the necessary prefix for
  42. #   USB disks, eg. '-d sat' or '-d usbjmicron' and so on -- please have a
  43. #   look at https://www.smartmontools.org/wiki/Supported_USB-Devices
  44. # - "temp call" when being omitted indicates that hddtemp should be used.
  45. #   Otherwise it should contain the complete command line ('DISK' will be
  46. #   dynamically replaced by the device node when the actual monitoring
  47. #   happens), for example:
  48. #   /sbin/hdparm -C DISK | egrep -q "standby|sleeping" || /usr/sbin/smartctl -d sat -a DISK | awk -F" " '/Temperature_Cel/ {printf $10}'
  49. # - 'CRC attribute': The decimal value of the S.M.A.R.T. attribute that
  50. #   is used to store the count of checksum errors between disk and host
  51. #   controller (might be omitted if the drive doesn't support it)
  52. # - 'LCC attribute': The decimal value of the S.M.A.R.T. attribute that
  53. #   should contain the load cycle counter value (might be omitted
  54. #   if the drive doesn't support it)
  55. #
  56. # TODO:
  57. #
  58. # - develop main functionality ;) asking the user regarding monitoring
  59. # - deal with 'SMART overall-health self-assessment test result:'
  60.  
  61. Main() {
  62.     PreRequisits
  63.  
  64.     # check whether user runs rpimonitord on his own or we activated it
  65.     if [ -f /etc/armbianmonitor/start-monitoring ]; then
  66.         # we should already provide monitoring, check whether DEBUG
  67.         # is also set
  68.         ArmbianMonitoring=TRUE
  69.         read DebugMode </etc/armbianmonitor/start-monitoring
  70.     fi
  71.    
  72.     # check whether rpimonitord is running and compare with ${ArmbianMonitoring}
  73.     # In case the user chose to run rpimonitord on his own, we skip the config
  74.     # part and only output disk info
  75.     :
  76.    
  77.     # check available disk devices
  78.     CheckDisks
  79. } # Main
  80.  
  81. CheckDisks() {
  82.     # This function walks through all block devices whose name starts with sd* and
  83.     # then gets the name hddtemp expects, the model name from smartctl, looks whether
  84.     # the drive only lists one temperature value and patches hddtemp.db if necessary
  85.     # and also tries to get CRC and LCC S.M.A.R.T. attributes to provide the user
  86.     # with the necessary config file contents for /etc/armbianmonitor/disks.conf:
  87.    
  88.     ls /sys/block/sd* >/dev/null 2>&1 || exit 0
  89.    
  90.     for i in /sys/block/sd* ; do
  91.         DeviceNode=/dev/${i##*/}
  92.         # get GUID/UUID for disk and check whether a partition table is existent. If
  93.         # not GUID will always be random
  94.         gdisk -l ${DeviceNode} >"${MyTempDir}/gdisk.txt"
  95.         GUID=$(awk -F" " '/^Disk identifier/ {print $4}' <"${MyTempDir}/gdisk.txt")
  96.         CountOfUnavailablePartitionTables=$(grep ': not present' "${MyTempDir}/gdisk.txt" | wc -l)
  97.         if [ ${CountOfUnavailablePartitionTables} -eq 4 ]; then
  98.             echo -e "\nSkipping ${DeviceNode} due to missing partition table. Use parted to create one."
  99.             break
  100.         else
  101.             echo -e "\nExamining ${DeviceNode} with GUID ${GUID}\c"
  102.         fi
  103.        
  104.         # get name hddtemp needs
  105.         HddtempName="$(hddtemp --debug ${DeviceNode} | awk -F": " '/^Model: / {print $2}' | \
  106.             cut -c-40 | sed 's/^[ \t]*//;s/[ \t]*$//')"
  107.         # store smartctl output in temporary file
  108.         smartctl -q noserial -s on -a ${DeviceNode} >"${MyTempDir}/smartctl.txt" 2>&1
  109.         DeviceModel="$(awk -F": " '/^Device Model/ {print $2}' <"${MyTempDir}/smartctl.txt" | \
  110.             sed 's/^[ \t]*//;s/[ \t]*$//')"
  111.         if [ "X${DeviceModel}" = "X" ]; then
  112.             # Reading S.M.A.R.T. failed, we try autodetect mode iterating through all
  113.             # known smartctl modes (-d auto|sat|usbcypress|usbjmicron|usbprolific|usbsunplus)
  114.             SMARTPrefix="$(CheckSMARTModes ${DeviceNode} 2>/dev/null)"
  115.             if [ "X${SMARTPrefix}" = "X" ]; then
  116.                 # we can't query the disk. Time to give up
  117.                 echo -e ". Unable to query the disk through S.M.A.R.T.\nPlease investigate manually using smartctl\n"
  118.                 break
  119.             fi
  120.         fi
  121.        
  122.         # user feedback
  123.         if [ "X${SMARTPrefix}" = "X" ]; then
  124.             echo -e " (accessible through S.M.A.R.T.)"
  125.         else
  126.             echo -e " (can be queried with \"-d ${SMARTPrefix}\" through S.M.A.R.T.)"
  127.         fi
  128.  
  129.         # check for CRC and LCC attributes
  130.         CRCAttribute=$(awk -F" " '/CRC_Error_Count/ {print $1}' <"${MyTempDir}/smartctl.txt")
  131.         LCCAttribute=$(grep -i "load.cycle" "${MyTempDir}/smartctl.txt" | awk -F" " '{print $1}')
  132.        
  133.         # check whether /etc/hddtemp.db should be patched
  134.         grep -q "${HddtempName}" /etc/hddtemp.db
  135.         if [ $? -ne 0 ]; then
  136.             # No entry into hddtemp database, we've a look whether there's a 'temperature'
  137.             # attribute available (we take the 1st we find) and if that's the case we use this
  138.             DiskTemp=$(awk -F" " '/Temperature/ {print $1}' <"${MyTempDir}/smartctl.txt" | head -n1)
  139.             if [[ ${DiskTemp} -gt 0 ]]; then
  140.                 echo -e "\"${HddtempName}\" ${DiskTemp} C \"${DeviceModel}\"" >>/etc/hddtemp.db
  141.                 echo -e "\nAdded disk \"${DeviceModel}\"/\"${HddtempName}\" to /etc/hddtemp.db using S.M.A.R.T. attribute ${DiskTemp}\nbased on the following available thermal values:"
  142.                 grep "Temperature" "${MyTempDir}/smartctl.txt"
  143.                 # check hddtemp result
  144.                 HddtempResult=$(hddtemp -n ${DeviceNode} | awk -F" " '{print $1}')
  145.                 if [ "X${HddtempResult}" = "X${DeviceNode}:" ]; then
  146.                     # hddtemp isn't able to query the disk
  147.                     HddtempStatus="does not work. Please check with smartctl and adjust config accordingly"
  148.                     echo -e "\nhddtemp output: $(hddtemp ${DeviceNode})"
  149.                     echo -e "\nIt seems we can not rely on hddtemp to query this disk. Please try smartctl instead\n"
  150.                 else
  151.                     HddtempStatus="will work"
  152.                     echo -e "\nhddtemp output: ${HddtempResult})"
  153.                     echo -e "\nIn case this seems not to be correct please adjust /etc/hddtemp.db manually\n"
  154.                 fi
  155.             else
  156.                 HddtempStatus="does not work. Please check with smartctl and adjust config accordingly"
  157.             fi
  158.         else
  159.             HddtempStatus="will work"
  160.         fi
  161.        
  162.         # check for firmware updates
  163.         FirmwareUpdate="$(grep "^http" "${MyTempDir}/smartctl.txt")"
  164.        
  165.         # Check whether the disk (based on GUID) is already configured in our config file
  166.         # /etc/armbianmonitor/disks.conf or not
  167.        
  168.         grep -q "^${GUID}:" /etc/armbianmonitor/disks.conf >/dev/null 2>/dev/null
  169.         case $? in
  170.             0)
  171.                 # already listed, we provide just infos:
  172.                 echo -e "Disk is already configured by the following monitoring config:\n$(grep "^${GUID}:" /etc/armbianmonitor/disks.conf)\n"
  173.                 ;;
  174.             *)
  175.                 # new disk, we recommend an entry for /etc/armbianmonitor/disks.conf
  176.                 echo -e "Disk not configured for monitoring. We were able to extract the following information:\nGUID: ${GUID}"
  177.                 if [ "X${SMARTPrefix}" != "X" ]; then
  178.                     echo -e "QueryMode: -d ${SMARTPrefix}"
  179.                 fi
  180.                 echo -e "hddtemp: ${HddtempStatus}\nCRC attribute: ${CRCAttribute}\nLCC Attribute: ${LCCAttribute}"
  181.                 case ${HddtempStatus} in
  182.                     "will work")
  183.                         echo -e "If you want to monitor the disk please add to /etc/armbianmonitor/disks.conf:\n${GUID}:${SMARTPrefix}::${CRCAttribute}:${LCCAttribute}"
  184.                         ;;
  185.                     *)
  186.                         echo -e "Proposal for /etc/armbianmonitor/disks.conf:\n${GUID}:${SMARTPrefix}:FIXME:${CRCAttribute}:${LCCAttribute}"
  187.                         echo -e "You have to figure out how to query the disk for its thermal sensor."
  188.                         echo -e "Please check the output of hddtemp --debug ${DeviceNode} and smartctl\n"
  189.                         ;;
  190.                 esac       
  191.                 ;;
  192.         esac
  193.         if [ "X${FirmwareUpdate}" != "X" ]; then
  194.             echo -e "\nWARNING: A firmware update seems to be available:\n${FirmwareUpdate}\n"
  195.         fi
  196.     done
  197. } # CheckDisks
  198.  
  199. CheckSMARTModes() {
  200.     # This function tries to access USB disks through S.M.A.R.T. and returns the necessary
  201.     # '-d' call as well as fills in ${MyTempDir}/smartctl.txt
  202.    
  203.     for i in auto sat usbcypress usbjmicron usbprolific usbsunplus ; do
  204.         # user feedback
  205.         echo -n "." >/dev/tty
  206.         # query disk using the specific protocol
  207.         echo -n "" >"${MyTempDir}/smartctl.txt"
  208.         smartctl -q noserial -s on -d ${i} -a ${1} >"${MyTempDir}/smartctl.txt" 2>/dev/null
  209.         DeviceModel="$(awk -F": " '/^Device Model/ {print $2}' <"${MyTempDir}/smartctl.txt" | \
  210.             sed 's/^[ \t]*//;s/[ \t]*$//')"
  211.         if [ "X${DeviceModel}" != "X" ]; then
  212.             echo ${i}
  213.             break
  214.         fi
  215.     done
  216. } # CheckSMARTModes
  217.  
  218. PreRequisits() {
  219.     # Ensure that we're running as root since otherwise querying SATA/USB disks won't work
  220.     if [ "$(id -u)" != "0" ]; then
  221.         echo "This script must be run as root" >&2
  222.         exit 1
  223.     fi
  224.  
  225.     export PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
  226.     unset LANG
  227.     DISTROCODE=$(lsb_release -s -c)
  228.    
  229.     # check whether gdisk/smartctl are available and up to date
  230.     echo -e "Check whether necessary software is available\c"
  231.     which gdisk >/dev/null 2>&1 || (echo -e " Installing gdisk\c" ; apt-get -f -qq -y install gdisk)
  232.     which smartctl >/dev/null 2>&1 || (echo -e " Installing smartmontools\c" ; apt-get -f -qq -y install smartmontools)
  233.     echo -e " [done]\nUpdating smartmontools' drivedb\c"
  234.     /usr/sbin/update-smart-drivedb >/dev/null 2>&1
  235.     if [ $? -ne 0 -a "X${DISTROCODE}" = "Xwheezy" ]; then
  236.         sed -i "/^SRCEXPR/{s#=.*#='http://sourceforge.net/p/smartmontools/code/HEAD/tree/\$location/smartmontools/drivedb.h?format=raw'#}" /usr/sbin/update-smart-drivedb
  237.         /usr/sbin/update-smart-drivedb
  238.     fi
  239.     echo -e " [done]"
  240.     CreateTempDir
  241. } # PreRequisits
  242.  
  243. CreateTempDir() {
  244.     # create a safe temporary dir
  245.     MyTempDir=$(mktemp -d /tmp/${0##*/}.XXXXXX)
  246.     if [ ! -d "${MyTempDir}" ]; then
  247.         MyTempDir=/tmp/${0##*/}.$RANDOM.$RANDOM.$RANDOM.$$
  248.         (umask 066 && mkdir ${MyTempDir}) || (echo "Failed to create temp dir. Aborting" >&2 ; exit 1)
  249.     fi
  250.     chmod 711 "${MyTempDir}"
  251.     trap "rm -rf \"${MyTempDir}\" ; exit 0" 0 1 2 3 15
  252.     for file in smartctl.txt gdisk.txt ; do
  253.         touch "${MyTempDir}/${file}"
  254.         chmod 644 "${MyTempDir}/${file}"
  255.     done
  256. } #CreateTempFiles
  257.  
  258. InstallRPiMonitor() {
  259.     # Installs rpimonitord based on the official instructions from
  260.     # http://rpi-experiences.blogspot.fr/p/rpi-monitor-installation.html
  261.     apt-get -f -qq -y install apt-transport-https ca-certificates
  262.     wget http://goo.gl/rsel0F -O /etc/apt/sources.list.d/rpimonitor.list
  263.     apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 2C0D3C0F
  264.     apt-get -f -qq -y update
  265.     apt-get -f -qq -y install rpimonitor
  266.     # apt-get -f -qq -y upgrade
  267.     /usr/share/rpimonitor/scripts/updatePackagesStatus.pl
  268. } # InstallRPiMonitor
  269.  
  270. Main
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top