smart 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. #!/bin/sh
  2. # {{{ Variables
  3. DEVICE=
  4. ATTRIBUTE=
  5. ATTRIBUTE_ID=
  6. SCAN=0
  7. ZBX_DISCOVERY_OUTPUT=0
  8. # }}}
  9. # {{{ usage()
  10. usage() {
  11. cat <<EOH
  12. USAGE: $(basename "$0") -d DEVICE -a ATTRIBUTE
  13. Get SMART attribute value for a device
  14. Options:
  15. -d Device path compatible with smarctl (e.g /dev/sda or '/dev/bus/0 -d megaraid,4')
  16. -a Attribute name or ID (e.g Temperature_Celsius, Offline_Uncorrectable, 194, 233, etc.)
  17. -S Scan devices and display list in a 'smartctl' compatible way
  18. -s Scan devices and display list in a 'smartctl' compatible way (Zabbix discovery output)
  19. EOH
  20. }
  21. # }}}
  22. # {{{ scan_megaraid_devices()
  23. scan_megaraid_devices() {
  24. if which storcli >/dev/null 2>&1 ; then
  25. ctrlcount=$(storcli show ctrlcount| sed -n 's/^Controller Count = //p')
  26. if [ "${ctrlcount}" -gt 0 ]; then
  27. ctrlcount=$(( ${ctrlcount} - 1))
  28. devices_ids=""
  29. for i in $(seq 0 ${ctrlcount}) ; do
  30. devices_ids="${devices_ids} $(storcli /c${i}/dall show| sed -r -n 's/\s*[0-9]+\s+[0-9]+\s+[0-9]+\s+[0-9]+:[0-9]+\s+([0-9]+)\s+DRIVE.*/\1/p' | xargs)"
  31. done
  32. for d in ${devices_ids} ; do
  33. printf "/dev/bus/0 -d sat+megaraid,${d}\n"
  34. done
  35. fi
  36. fi
  37. }
  38. # }}}
  39. # {{{ scan_devices()
  40. scan_devices() {
  41. find /dev -regex '/dev/sg[0-9]'
  42. find /dev -regex '/dev/sd[a-z]'
  43. smartctl --scan | \
  44. sed -r 's/\s+#.*$//' | \
  45. sed 's/megaraid/sat+megaraid/g'
  46. scan_megaraid_devices
  47. }
  48. # }}}
  49. # {{{ list_smart_devices()
  50. list_smart_devices() {
  51. ZBX="${1}"
  52. if [ "${ZBX}" = 1 ]; then
  53. printf '{"data":['
  54. fi
  55. if which smartctl >/dev/null 2>&1 ; then
  56. serials=""
  57. scan_devices | \
  58. while read d ; do
  59. diskinfo=$(smartctl -i $d)
  60. if echo "${diskinfo}" | egrep -q '^Device is:' ; then
  61. serial=$(echo "${diskinfo}" | sed -r -n 's/^Serial Number:\s+(.*)$/\1/p')
  62. if ! echo "${serials}" | grep -q "${serial}" ; then
  63. serials="${serials} ${serial}"
  64. capacity=$(echo "${diskinfo}" | sed -r -n 's/User Capacity:\s+.*\[(.*)\]$/\1/p')
  65. hwrot=$(echo "${diskinfo}" | sed -r -n 's/Rotation Rate:\s+(.*)$/\1/p')
  66. if [ "${ZBX}" = 1 ]; then
  67. printf '{'
  68. printf '"{#DEVICE}":"%s",' "${d}"
  69. printf '"{#SERIAL}":"%s",' "${serial}"
  70. printf '"{#CAPACITY}":"%s",' "${capacity}"
  71. printf '"{#HWROT}":"%s"' "${hwrot}"
  72. printf '},'
  73. else
  74. echo "${d}|${serial}|${capacity}|${hwrot}"
  75. fi
  76. fi
  77. fi
  78. done | sed 's/},$/}/'
  79. fi
  80. if [ "${ZBX}" = 1 ]; then
  81. printf ']}'
  82. fi
  83. }
  84. # }}}
  85. # {{{ main()
  86. while getopts "d:a:Ss" OPT ; do
  87. case "$OPT" in
  88. \?|h)
  89. usage
  90. exit 0
  91. ;;
  92. d)
  93. DEVICE="$OPTARG"
  94. ;;
  95. a)
  96. ATTRIBUTE="$OPTARG"
  97. ;;
  98. S)
  99. SCAN=1
  100. ;;
  101. s)
  102. SCAN=1
  103. ZBX_DISCOVERY_OUTPUT=1
  104. ;;
  105. esac
  106. done
  107. if [ "${SCAN}" = 1 ]; then
  108. list_smart_devices "${ZBX_DISCOVERY_OUTPUT}"
  109. exit 0
  110. fi
  111. if [ -z "${DEVICE}" ] ; then
  112. printf "[ERR] device is not defined\n"
  113. usage
  114. exit 1
  115. fi
  116. if [ -z "${ATTRIBUTE}" ] ; then
  117. printf "[ERR] attribute name or attribute ID is not defined\n"
  118. usage
  119. exit 1
  120. fi
  121. if echo "${ATTRIBUTE}" | egrep -q '^[[:digit:]]+$'; then
  122. data=$(smartctl -A ${DEVICE} | egrep "^[[:space:]]*${ATTRIBUTE}[[:space:]]+[A-Z]+")
  123. else
  124. data=$(smartctl -A ${DEVICE} | egrep "^[[:space:]]*[[:digit:]]+[[:space:]]+${ATTRIBUTE}")
  125. fi
  126. if [ $? != 0 ]; then
  127. printf -- "-1\n"
  128. else
  129. printf "${data}\n" | \
  130. tr -s ' ' | \
  131. sed 's/^[[:space:]]*\(.*\)[[:space:]]*$/\1/' | \
  132. cut -d ' ' -f 10
  133. fi
  134. exit 0
  135. # }}}
  136. # vim: foldmethod=marker foldlevel=0 foldenable