SHARE
TWEET

armbian-monitoring

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