chiark / gitweb /
check.d/{disks,ntp}: Only perform the checks if relevant programs exist.
[rcheck] / check.d / disks
1 #! /bin/bash
2 ###
3 ### Check the health of attached physical disks.
4
5 set -e
6 if [ ! -x /usr/sbin/smartctl ]; then exit 0; fi
7
8 ## Build a list of actual disk devices according to their buses.
9 disks=
10 for p in /sys/class/block/*; do
11   bus=none devtype=none idtype=none
12   while read code assg; do
13     case "$assg" in
14       DEVNAME=*) name=${assg#*=} ;;
15       ID_BUS=*) bus=${assg#*=} ;;
16       DEVTYPE=*) devtype=${assg#*=} ;;
17       ID_TYPE=*) idtype=${assg#*=} ;;
18     esac
19   done <<EOF
20 $(udevadm info --query=all --path=$p)
21 EOF
22   case "$bus,$devtype,$idtype" in
23     ata,disk,disk | scsi,disk,disk) disks=${disks+$disks }$name ;;
24   esac
25 done
26
27 ## Now go through each disk.
28 for disk in $disks; do
29   set +e; smartctl -qsilent $disk; rc=$?; set -e
30   if (( $rc & 2 )); then continue; fi
31
32   if (( $rc & 8 )); then echo "W: SMART reports disk $disk failing"; fi
33
34   smartctl -A $disk |
35   while read id attr flag value worst thresh type upd when raw; do
36     case "$id" in *[!0-9]*) continue ;; ?*) ;; *) continue ;; esac
37     while :; do
38       case "$value" in 0*?) value=${value#0} ;; *) break ;; esac;
39     done
40     while :; do
41       case "$thresh" in 0*?) thresh=${thresh#0} ;; *) break ;; esac;
42     done
43     case "$attr,$raw,$when" in
44       Current_Pending_Sector,*[!0]*,*)
45         echo "W: disk $disk has $raw pending sector(s)"
46         ;;
47       Offline_Uncorrectable,*[!0]*,*)
48         echo "W: disk $disk has $raw offline-uncorrectable sector(s)"
49         ;;
50       *,*,FAILING_NOW)
51         echo "W: disk $disk attribute $attr failing (value = $raw)"
52         ;;
53       *)
54         if (( $value < $thresh )); then
55           echo "I: disk $disk attribute $attr below thresh (value = $raw)"
56         fi
57         ;;
58     esac
59   done
60 done