Advertisement
Guest User

armbian-monitoring

a guest
Jan 19th, 2016
201
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 11.58 KB | None | 0 0
  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
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement