Advertisement
Guest User

armbian-monitoring

a guest
Jan 28th, 2016
455
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.83 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}:${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
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement