diff options
Diffstat (limited to 'plugins/check_ide_smart.c')
-rw-r--r-- | plugins/check_ide_smart.c | 580 |
1 files changed, 253 insertions, 327 deletions
diff --git a/plugins/check_ide_smart.c b/plugins/check_ide_smart.c index 3872e341..16fe3d01 100644 --- a/plugins/check_ide_smart.c +++ b/plugins/check_ide_smart.c | |||
@@ -1,240 +1,211 @@ | |||
1 | /***************************************************************************** | 1 | /***************************************************************************** |
2 | * | 2 | * |
3 | * Monitoring check_ide_smart plugin | 3 | * Monitoring check_ide_smart plugin |
4 | * ide-smart 1.3 - IDE S.M.A.R.T. checking tool | 4 | * ide-smart 1.3 - IDE S.M.A.R.T. checking tool |
5 | * | 5 | * |
6 | * License: GPL | 6 | * License: GPL |
7 | * Copyright (C) 1998-1999 Ragnar Hojland Espinosa <ragnar@lightside.dhis.org> | 7 | * Copyright (C) 1998-1999 Ragnar Hojland Espinosa <ragnar@lightside.dhis.org> |
8 | * 1998 Gadi Oxman <gadio@netvision.net.il> | 8 | * 1998 Gadi Oxman <gadio@netvision.net.il> |
9 | * Copyright (c) 2000 Robert Dale <rdale@digital-mission.com> | 9 | * Copyright (c) 2000 Robert Dale <rdale@digital-mission.com> |
10 | * Copyright (c) 2000-2007 Monitoring Plugins Development Team | 10 | * Copyright (c) 2000-2024 Monitoring Plugins Development Team |
11 | * | 11 | * |
12 | * Description: | 12 | * Description: |
13 | * | 13 | * |
14 | * This file contains the check_ide_smart plugin | 14 | * This file contains the check_ide_smart plugin |
15 | * | 15 | * |
16 | * This plugin checks a local hard drive with the (Linux specific) SMART | 16 | * This plugin checks a local hard drive with the (Linux specific) SMART |
17 | * interface | 17 | * interface |
18 | * | 18 | * |
19 | * | 19 | * |
20 | * This program is free software: you can redistribute it and/or modify | 20 | * This program is free software: you can redistribute it and/or modify |
21 | * it under the terms of the GNU General Public License as published by | 21 | * it under the terms of the GNU General Public License as published by |
22 | * the Free Software Foundation, either version 3 of the License, or | 22 | * the Free Software Foundation, either version 3 of the License, or |
23 | * (at your option) any later version. | 23 | * (at your option) any later version. |
24 | * | 24 | * |
25 | * This program is distributed in the hope that it will be useful, | 25 | * This program is distributed in the hope that it will be useful, |
26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
28 | * GNU General Public License for more details. | 28 | * GNU General Public License for more details. |
29 | * | 29 | * |
30 | * You should have received a copy of the GNU General Public License | 30 | * You should have received a copy of the GNU General Public License |
31 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 31 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
32 | * | 32 | * |
33 | * | 33 | * |
34 | *****************************************************************************/ | 34 | *****************************************************************************/ |
35 | 35 | ||
36 | const char *progname = "check_ide_smart"; | 36 | const char *progname = "check_ide_smart"; |
37 | const char *copyright = "1998-2007"; | 37 | const char *copyright = "1998-2024"; |
38 | const char *email = "devel@monitoring-plugins.org"; | 38 | const char *email = "devel@monitoring-plugins.org"; |
39 | 39 | ||
40 | #include "common.h" | 40 | #include "common.h" |
41 | #include "utils.h" | 41 | #include "utils.h" |
42 | 42 | ||
43 | void print_help (void); | 43 | static void print_help(void); |
44 | void print_usage (void); | 44 | void print_usage(void); |
45 | 45 | ||
46 | #include <sys/stat.h> | 46 | #include <sys/stat.h> |
47 | #include <sys/ioctl.h> | 47 | #include <sys/ioctl.h> |
48 | #include <fcntl.h> | 48 | #include <fcntl.h> |
49 | #ifdef __linux__ | 49 | #ifdef __linux__ |
50 | #include <linux/hdreg.h> | 50 | # include <linux/hdreg.h> |
51 | #include <linux/types.h> | 51 | # include <linux/types.h> |
52 | 52 | ||
53 | #define OPEN_MODE O_RDONLY | 53 | # define OPEN_MODE O_RDONLY |
54 | #endif /* __linux__ */ | 54 | #endif /* __linux__ */ |
55 | #ifdef __NetBSD__ | 55 | #ifdef __NetBSD__ |
56 | #include <sys/device.h> | 56 | # include <sys/device.h> |
57 | #include <sys/param.h> | 57 | # include <sys/param.h> |
58 | #include <sys/sysctl.h> | 58 | # include <sys/sysctl.h> |
59 | #include <sys/videoio.h> /* for __u8 and friends */ | 59 | # include <sys/scsiio.h> |
60 | #include <sys/scsiio.h> | 60 | # include <sys/ataio.h> |
61 | #include <sys/ataio.h> | 61 | # include <dev/ata/atareg.h> |
62 | #include <dev/ata/atareg.h> | 62 | # include <dev/ic/wdcreg.h> |
63 | #include <dev/ic/wdcreg.h> | 63 | |
64 | 64 | # define SMART_ENABLE WDSM_ENABLE_OPS | |
65 | #define SMART_ENABLE WDSM_ENABLE_OPS | 65 | # define SMART_DISABLE WDSM_DISABLE_OPS |
66 | #define SMART_DISABLE WDSM_DISABLE_OPS | 66 | # define SMART_IMMEDIATE_OFFLINE WDSM_EXEC_OFFL_IMM |
67 | #define SMART_IMMEDIATE_OFFLINE WDSM_EXEC_OFFL_IMM | 67 | # define SMART_AUTO_OFFLINE 0xdb /* undefined in NetBSD headers */ |
68 | #define SMART_AUTO_OFFLINE 0xdb /* undefined in NetBSD headers */ | 68 | |
69 | 69 | # define OPEN_MODE O_RDWR | |
70 | #define OPEN_MODE O_RDWR | ||
71 | #endif /* __NetBSD__ */ | 70 | #endif /* __NetBSD__ */ |
72 | #include <errno.h> | 71 | #include <errno.h> |
73 | 72 | ||
74 | #define NR_ATTRIBUTES 30 | 73 | #define NR_ATTRIBUTES 30 |
75 | 74 | ||
76 | #define PREFAILURE 2 | 75 | #define PREFAILURE 2 |
77 | #define ADVISORY 1 | 76 | #define ADVISORY 1 |
78 | #define OPERATIONAL 0 | 77 | #define OPERATIONAL 0 |
79 | #define UNKNOWN -1 | 78 | #define UNKNOWN -1 |
80 | 79 | ||
81 | typedef struct threshold_s | 80 | typedef struct threshold_s { |
82 | { | 81 | uint8_t id; |
83 | __u8 id; | 82 | uint8_t threshold; |
84 | __u8 threshold; | 83 | uint8_t reserved[10]; |
85 | __u8 reserved[10]; | 84 | } __attribute__((packed)) threshold_t; |
86 | } | ||
87 | __attribute__ ((packed)) threshold_t; | ||
88 | 85 | ||
89 | typedef struct thresholds_s | 86 | typedef struct thresholds_s { |
90 | { | 87 | uint16_t revision; |
91 | __u16 revision; | ||
92 | threshold_t thresholds[NR_ATTRIBUTES]; | 88 | threshold_t thresholds[NR_ATTRIBUTES]; |
93 | __u8 reserved[18]; | 89 | uint8_t reserved[18]; |
94 | __u8 vendor[131]; | 90 | uint8_t vendor[131]; |
95 | __u8 checksum; | 91 | uint8_t checksum; |
96 | } | 92 | } __attribute__((packed)) thresholds_t; |
97 | __attribute__ ((packed)) thresholds_t; | 93 | |
98 | 94 | typedef struct value_s { | |
99 | typedef struct value_s | 95 | uint8_t id; |
100 | { | 96 | uint16_t status; |
101 | __u8 id; | 97 | uint8_t value; |
102 | __u16 status; | 98 | uint8_t vendor[8]; |
103 | __u8 value; | 99 | } __attribute__((packed)) value_t; |
104 | __u8 vendor[8]; | 100 | |
105 | } | 101 | typedef struct values_s { |
106 | __attribute__ ((packed)) value_t; | 102 | uint16_t revision; |
107 | |||
108 | typedef struct values_s | ||
109 | { | ||
110 | __u16 revision; | ||
111 | value_t values[NR_ATTRIBUTES]; | 103 | value_t values[NR_ATTRIBUTES]; |
112 | __u8 offline_status; | 104 | uint8_t offline_status; |
113 | __u8 vendor1; | 105 | uint8_t vendor1; |
114 | __u16 offline_timeout; | 106 | uint16_t offline_timeout; |
115 | __u8 vendor2; | 107 | uint8_t vendor2; |
116 | __u8 offline_capability; | 108 | uint8_t offline_capability; |
117 | __u16 smart_capability; | 109 | uint16_t smart_capability; |
118 | __u8 reserved[16]; | 110 | uint8_t reserved[16]; |
119 | __u8 vendor[125]; | 111 | uint8_t vendor[125]; |
120 | __u8 checksum; | 112 | uint8_t checksum; |
121 | } | 113 | } __attribute__((packed)) values_t; |
122 | __attribute__ ((packed)) values_t; | 114 | |
123 | 115 | static struct { | |
124 | struct | 116 | uint8_t value; |
125 | { | ||
126 | __u8 value; | ||
127 | char *text; | 117 | char *text; |
128 | } | 118 | } offline_status_text[] = {{0x00, "NeverStarted"}, {0x02, "Completed"}, {0x04, "Suspended"}, {0x05, "Aborted"}, {0x06, "Failed"}, {0, 0}}; |
129 | 119 | ||
130 | offline_status_text[] = | 120 | static struct { |
131 | { | 121 | uint8_t value; |
132 | {0x00, "NeverStarted"}, | ||
133 | {0x02, "Completed"}, | ||
134 | {0x04, "Suspended"}, | ||
135 | {0x05, "Aborted"}, | ||
136 | {0x06, "Failed"}, | ||
137 | {0, 0} | ||
138 | }; | ||
139 | |||
140 | struct | ||
141 | { | ||
142 | __u8 value; | ||
143 | char *text; | 122 | char *text; |
144 | } | 123 | } smart_command[] = {{SMART_ENABLE, "SMART_ENABLE"}, |
145 | 124 | {SMART_DISABLE, "SMART_DISABLE"}, | |
146 | smart_command[] = | 125 | {SMART_IMMEDIATE_OFFLINE, "SMART_IMMEDIATE_OFFLINE"}, |
147 | { | 126 | {SMART_AUTO_OFFLINE, "SMART_AUTO_OFFLINE"}}; |
148 | {SMART_ENABLE, "SMART_ENABLE"}, | 127 | |
149 | {SMART_DISABLE, "SMART_DISABLE"}, | 128 | /* Index to smart_command table, keep in order */ |
150 | {SMART_IMMEDIATE_OFFLINE, "SMART_IMMEDIATE_OFFLINE"}, | 129 | enum SmartCommand { |
151 | {SMART_AUTO_OFFLINE, "SMART_AUTO_OFFLINE"} | 130 | SMART_CMD_ENABLE, |
152 | }; | 131 | SMART_CMD_DISABLE, |
153 | 132 | SMART_CMD_IMMEDIATE_OFFLINE, | |
154 | 133 | SMART_CMD_AUTO_OFFLINE | |
155 | /* Index to smart_command table, keep in order */ | 134 | }; |
156 | enum SmartCommand | 135 | |
157 | { SMART_CMD_ENABLE, | 136 | static char *get_offline_text(int); |
158 | SMART_CMD_DISABLE, | 137 | static int smart_read_values(int, values_t *); |
159 | SMART_CMD_IMMEDIATE_OFFLINE, | 138 | static int nagios(values_t *, thresholds_t *); |
160 | SMART_CMD_AUTO_OFFLINE | 139 | static void print_value(value_t *, threshold_t *); |
161 | }; | 140 | static void print_values(values_t *, thresholds_t *); |
162 | 141 | static int smart_cmd_simple(int, enum SmartCommand, uint8_t, bool); | |
163 | char *get_offline_text (int); | 142 | static int smart_read_thresholds(int, thresholds_t *); |
164 | int smart_read_values (int, values_t *); | 143 | static bool verbose = false; |
165 | int nagios (values_t *, thresholds_t *); | 144 | |
166 | void print_value (value_t *, threshold_t *); | 145 | int main(int argc, char *argv[]) { |
167 | void print_values (values_t *, thresholds_t *); | ||
168 | int smart_cmd_simple (int, enum SmartCommand, __u8, bool); | ||
169 | int smart_read_thresholds (int, thresholds_t *); | ||
170 | bool verbose = false; | ||
171 | |||
172 | int | ||
173 | main (int argc, char *argv[]) | ||
174 | { | ||
175 | char *device = NULL; | 146 | char *device = NULL; |
176 | int o, longindex; | 147 | int o; |
148 | int longindex; | ||
177 | int retval = 0; | 149 | int retval = 0; |
178 | 150 | ||
179 | thresholds_t thresholds; | 151 | thresholds_t thresholds; |
180 | values_t values; | 152 | values_t values; |
181 | int fd; | 153 | int fd; |
182 | 154 | ||
183 | static struct option longopts[] = { | 155 | static struct option longopts[] = {{"device", required_argument, 0, 'd'}, |
184 | {"device", required_argument, 0, 'd'}, | 156 | {"immediate", no_argument, 0, 'i'}, |
185 | {"immediate", no_argument, 0, 'i'}, | 157 | {"quiet-check", no_argument, 0, 'q'}, |
186 | {"quiet-check", no_argument, 0, 'q'}, | 158 | {"auto-on", no_argument, 0, '1'}, |
187 | {"auto-on", no_argument, 0, '1'}, | 159 | {"auto-off", no_argument, 0, '0'}, |
188 | {"auto-off", no_argument, 0, '0'}, | 160 | {"nagios", no_argument, 0, 'n'}, /* DEPRECATED, but we still accept it */ |
189 | {"nagios", no_argument, 0, 'n'}, /* DEPRECATED, but we still accept it */ | 161 | {"help", no_argument, 0, 'h'}, |
190 | {"help", no_argument, 0, 'h'}, | 162 | {"version", no_argument, 0, 'V'}, |
191 | {"version", no_argument, 0, 'V'}, | 163 | {0, 0, 0, 0}}; |
192 | {0, 0, 0, 0} | ||
193 | }; | ||
194 | 164 | ||
195 | /* Parse extra opts if any */ | 165 | /* Parse extra opts if any */ |
196 | argv=np_extra_opts (&argc, argv, progname); | 166 | argv = np_extra_opts(&argc, argv, progname); |
197 | 167 | ||
198 | setlocale (LC_ALL, ""); | 168 | setlocale(LC_ALL, ""); |
199 | bindtextdomain (PACKAGE, LOCALEDIR); | 169 | bindtextdomain(PACKAGE, LOCALEDIR); |
200 | textdomain (PACKAGE); | 170 | textdomain(PACKAGE); |
201 | 171 | ||
202 | while (true) { | 172 | while (true) { |
203 | |||
204 | o = getopt_long (argc, argv, "+d:iq10nhVv", longopts, &longindex); | ||
205 | 173 | ||
206 | if (o == -1 || o == EOF || o == 1) | 174 | o = getopt_long(argc, argv, "+d:iq10nhVv", longopts, &longindex); |
175 | |||
176 | if (o == -1 || o == EOF || o == 1) { | ||
207 | break; | 177 | break; |
178 | } | ||
208 | 179 | ||
209 | switch (o) { | 180 | switch (o) { |
210 | case 'd': | 181 | case 'd': |
211 | device = optarg; | 182 | device = optarg; |
212 | break; | 183 | break; |
213 | case 'q': | 184 | case 'q': |
214 | fprintf (stderr, "%s\n", _("DEPRECATION WARNING: the -q switch (quiet output) is no longer \"quiet\".")); | 185 | fprintf(stderr, "%s\n", _("DEPRECATION WARNING: the -q switch (quiet output) is no longer \"quiet\".")); |
215 | fprintf (stderr, "%s\n", _("Nagios-compatible output is now always returned.")); | 186 | fprintf(stderr, "%s\n", _("Nagios-compatible output is now always returned.")); |
216 | break; | 187 | break; |
217 | case 'i': | 188 | case 'i': |
218 | case '1': | 189 | case '1': |
219 | case '0': | 190 | case '0': |
220 | printf ("%s\n", _("SMART commands are broken and have been disabled (See Notes in --help).")); | 191 | printf("%s\n", _("SMART commands are broken and have been disabled (See Notes in --help).")); |
221 | return STATE_CRITICAL; | 192 | return STATE_CRITICAL; |
222 | break; | 193 | break; |
223 | case 'n': | 194 | case 'n': |
224 | fprintf (stderr, "%s\n", _("DEPRECATION WARNING: the -n switch (Nagios-compatible output) is now the")); | 195 | fprintf(stderr, "%s\n", _("DEPRECATION WARNING: the -n switch (Nagios-compatible output) is now the")); |
225 | fprintf (stderr, "%s\n", _("default and will be removed from future releases.")); | 196 | fprintf(stderr, "%s\n", _("default and will be removed from future releases.")); |
226 | break; | 197 | break; |
227 | case 'v': /* verbose */ | 198 | case 'v': /* verbose */ |
228 | verbose = true; | 199 | verbose = true; |
229 | break; | 200 | break; |
230 | case 'h': | 201 | case 'h': |
231 | print_help (); | 202 | print_help(); |
232 | return STATE_UNKNOWN; | 203 | return STATE_UNKNOWN; |
233 | case 'V': | 204 | case 'V': |
234 | print_revision (progname, NP_VERSION); | 205 | print_revision(progname, NP_VERSION); |
235 | return STATE_UNKNOWN; | 206 | return STATE_UNKNOWN; |
236 | default: | 207 | default: |
237 | usage5 (); | 208 | usage5(); |
238 | } | 209 | } |
239 | } | 210 | } |
240 | 211 | ||
@@ -243,36 +214,34 @@ main (int argc, char *argv[]) | |||
243 | } | 214 | } |
244 | 215 | ||
245 | if (!device) { | 216 | if (!device) { |
246 | print_help (); | 217 | print_help(); |
247 | return STATE_UNKNOWN; | 218 | return STATE_UNKNOWN; |
248 | } | 219 | } |
249 | 220 | ||
250 | fd = open (device, OPEN_MODE); | 221 | fd = open(device, OPEN_MODE); |
251 | 222 | ||
252 | if (fd < 0) { | 223 | if (fd < 0) { |
253 | printf (_("CRITICAL - Couldn't open device %s: %s\n"), device, strerror (errno)); | 224 | printf(_("CRITICAL - Couldn't open device %s: %s\n"), device, strerror(errno)); |
254 | return STATE_CRITICAL; | 225 | return STATE_CRITICAL; |
255 | } | 226 | } |
256 | 227 | ||
257 | if (smart_cmd_simple (fd, SMART_CMD_ENABLE, 0, false)) { | 228 | if (smart_cmd_simple(fd, SMART_CMD_ENABLE, 0, false)) { |
258 | printf (_("CRITICAL - SMART_CMD_ENABLE\n")); | 229 | printf(_("CRITICAL - SMART_CMD_ENABLE\n")); |
259 | return STATE_CRITICAL; | 230 | return STATE_CRITICAL; |
260 | } | 231 | } |
261 | 232 | ||
262 | smart_read_values (fd, &values); | 233 | smart_read_values(fd, &values); |
263 | smart_read_thresholds (fd, &thresholds); | 234 | smart_read_thresholds(fd, &thresholds); |
264 | retval = nagios (&values, &thresholds); | 235 | retval = nagios(&values, &thresholds); |
265 | if (verbose) print_values (&values, &thresholds); | 236 | if (verbose) { |
237 | print_values(&values, &thresholds); | ||
238 | } | ||
266 | 239 | ||
267 | close (fd); | 240 | close(fd); |
268 | return retval; | 241 | return retval; |
269 | } | 242 | } |
270 | 243 | ||
271 | 244 | char *get_offline_text(int status) { | |
272 | |||
273 | char * | ||
274 | get_offline_text (int status) | ||
275 | { | ||
276 | int i; | 245 | int i; |
277 | for (i = 0; offline_status_text[i].text; i++) { | 246 | for (i = 0; offline_status_text[i].text; i++) { |
278 | if (offline_status_text[i].value == status) { | 247 | if (offline_status_text[i].value == status) { |
@@ -282,24 +251,20 @@ get_offline_text (int status) | |||
282 | return "UNKNOWN"; | 251 | return "UNKNOWN"; |
283 | } | 252 | } |
284 | 253 | ||
285 | 254 | int smart_read_values(int fd, values_t *values) { | |
286 | |||
287 | int | ||
288 | smart_read_values (int fd, values_t * values) | ||
289 | { | ||
290 | #ifdef __linux__ | 255 | #ifdef __linux__ |
291 | int e; | 256 | int e; |
292 | __u8 args[4 + 512]; | 257 | uint8_t args[4 + 512]; |
293 | args[0] = WIN_SMART; | 258 | args[0] = WIN_SMART; |
294 | args[1] = 0; | 259 | args[1] = 0; |
295 | args[2] = SMART_READ_VALUES; | 260 | args[2] = SMART_READ_VALUES; |
296 | args[3] = 1; | 261 | args[3] = 1; |
297 | if (ioctl (fd, HDIO_DRIVE_CMD, &args)) { | 262 | if (ioctl(fd, HDIO_DRIVE_CMD, &args)) { |
298 | e = errno; | 263 | e = errno; |
299 | printf (_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror (errno)); | 264 | printf(_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror(errno)); |
300 | return e; | 265 | return e; |
301 | } | 266 | } |
302 | memcpy (values, args + 4, 512); | 267 | memcpy(values, args + 4, 512); |
303 | #endif /* __linux__ */ | 268 | #endif /* __linux__ */ |
304 | #ifdef __NetBSD__ | 269 | #ifdef __NetBSD__ |
305 | struct atareq req; | 270 | struct atareq req; |
@@ -317,13 +282,14 @@ smart_read_values (int fd, values_t * values) | |||
317 | req.cylinder = WDSMART_CYL; | 282 | req.cylinder = WDSMART_CYL; |
318 | 283 | ||
319 | if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { | 284 | if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { |
320 | if (req.retsts != ATACMD_OK) | 285 | if (req.retsts != ATACMD_OK) { |
321 | errno = ENODEV; | 286 | errno = ENODEV; |
287 | } | ||
322 | } | 288 | } |
323 | 289 | ||
324 | if (errno != 0) { | 290 | if (errno != 0) { |
325 | int e = errno; | 291 | int e = errno; |
326 | printf (_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror (errno)); | 292 | printf(_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror(errno)); |
327 | return e; | 293 | return e; |
328 | } | 294 | } |
329 | 295 | ||
@@ -332,13 +298,9 @@ smart_read_values (int fd, values_t * values) | |||
332 | return 0; | 298 | return 0; |
333 | } | 299 | } |
334 | 300 | ||
335 | 301 | int nagios(values_t *p, thresholds_t *t) { | |
336 | 302 | value_t *value = p->values; | |
337 | int | 303 | threshold_t *threshold = t->thresholds; |
338 | nagios (values_t * p, thresholds_t * t) | ||
339 | { | ||
340 | value_t * value = p->values; | ||
341 | threshold_t * threshold = t->thresholds; | ||
342 | int status = OPERATIONAL; | 304 | int status = OPERATIONAL; |
343 | int prefailure = 0; | 305 | int prefailure = 0; |
344 | int advisory = 0; | 306 | int advisory = 0; |
@@ -353,13 +315,11 @@ nagios (values_t * p, thresholds_t * t) | |||
353 | if (value->status & 1) { | 315 | if (value->status & 1) { |
354 | status = PREFAILURE; | 316 | status = PREFAILURE; |
355 | ++prefailure; | 317 | ++prefailure; |
356 | } | 318 | } else { |
357 | else { | ||
358 | status = ADVISORY; | 319 | status = ADVISORY; |
359 | ++advisory; | 320 | ++advisory; |
360 | } | 321 | } |
361 | } | 322 | } else { |
362 | else { | ||
363 | ++passed; | 323 | ++passed; |
364 | } | 324 | } |
365 | ++total; | 325 | ++total; |
@@ -369,96 +329,66 @@ nagios (values_t * p, thresholds_t * t) | |||
369 | } | 329 | } |
370 | switch (status) { | 330 | switch (status) { |
371 | case PREFAILURE: | 331 | case PREFAILURE: |
372 | printf (_("CRITICAL - %d Harddrive PreFailure%cDetected! %d/%d tests failed.\n"), | 332 | printf(_("CRITICAL - %d Harddrive PreFailure%cDetected! %d/%d tests failed.\n"), prefailure, prefailure > 1 ? 's' : ' ', failed, |
373 | prefailure, | 333 | total); |
374 | prefailure > 1 ? 's' : ' ', | 334 | status = STATE_CRITICAL; |
375 | failed, | ||
376 | total); | ||
377 | status=STATE_CRITICAL; | ||
378 | break; | 335 | break; |
379 | case ADVISORY: | 336 | case ADVISORY: |
380 | printf (_("WARNING - %d Harddrive Advisor%s Detected. %d/%d tests failed.\n"), | 337 | printf(_("WARNING - %d Harddrive Advisor%s Detected. %d/%d tests failed.\n"), advisory, advisory > 1 ? "ies" : "y", failed, total); |
381 | advisory, | 338 | status = STATE_WARNING; |
382 | advisory > 1 ? "ies" : "y", | ||
383 | failed, | ||
384 | total); | ||
385 | status=STATE_WARNING; | ||
386 | break; | 339 | break; |
387 | case OPERATIONAL: | 340 | case OPERATIONAL: |
388 | printf (_("OK - Operational (%d/%d tests passed)\n"), passed, total); | 341 | printf(_("OK - Operational (%d/%d tests passed)\n"), passed, total); |
389 | status=STATE_OK; | 342 | status = STATE_OK; |
390 | break; | 343 | break; |
391 | default: | 344 | default: |
392 | printf (_("ERROR - Status '%d' unknown. %d/%d tests passed\n"), status, | 345 | printf(_("ERROR - Status '%d' unknown. %d/%d tests passed\n"), status, passed, total); |
393 | passed, total); | ||
394 | status = STATE_UNKNOWN; | 346 | status = STATE_UNKNOWN; |
395 | break; | 347 | break; |
396 | } | 348 | } |
397 | return status; | 349 | return status; |
398 | } | 350 | } |
399 | 351 | ||
400 | 352 | void print_value(value_t *p, threshold_t *t) { | |
401 | 353 | printf("Id=%3d, Status=%2d {%s , %s}, Value=%3d, Threshold=%3d, %s\n", p->id, p->status, p->status & 1 ? "PreFailure" : "Advisory ", | |
402 | void | 354 | p->status & 2 ? "OnLine " : "OffLine", p->value, t->threshold, p->value >= t->threshold ? "Passed" : "Failed"); |
403 | print_value (value_t * p, threshold_t * t) | ||
404 | { | ||
405 | printf ("Id=%3d, Status=%2d {%s , %s}, Value=%3d, Threshold=%3d, %s\n", | ||
406 | p->id, p->status, p->status & 1 ? "PreFailure" : "Advisory ", | ||
407 | p->status & 2 ? "OnLine " : "OffLine", p->value, t->threshold, | ||
408 | p->value >= t->threshold ? "Passed" : "Failed"); | ||
409 | } | 355 | } |
410 | 356 | ||
411 | 357 | void print_values(values_t *p, thresholds_t *t) { | |
412 | 358 | value_t *value = p->values; | |
413 | void | 359 | threshold_t *threshold = t->thresholds; |
414 | print_values (values_t * p, thresholds_t * t) | ||
415 | { | ||
416 | value_t * value = p->values; | ||
417 | threshold_t * threshold = t->thresholds; | ||
418 | int i; | 360 | int i; |
419 | for (i = 0; i < NR_ATTRIBUTES; i++) { | 361 | for (i = 0; i < NR_ATTRIBUTES; i++) { |
420 | if (value->id && threshold->id && value->id == threshold->id) { | 362 | if (value->id && threshold->id && value->id == threshold->id) { |
421 | print_value (value++, threshold++); | 363 | print_value(value++, threshold++); |
422 | } | 364 | } |
423 | } | 365 | } |
424 | printf | 366 | printf(_("OffLineStatus=%d {%s}, AutoOffLine=%s, OffLineTimeout=%d minutes\n"), p->offline_status, |
425 | (_("OffLineStatus=%d {%s}, AutoOffLine=%s, OffLineTimeout=%d minutes\n"), | 367 | get_offline_text(p->offline_status & 0x7f), (p->offline_status & 0x80 ? "Yes" : "No"), p->offline_timeout / 60); |
426 | p->offline_status, | 368 | printf(_("OffLineCapability=%d {%s %s %s}\n"), p->offline_capability, p->offline_capability & 1 ? "Immediate" : "", |
427 | get_offline_text (p->offline_status & 0x7f), | 369 | p->offline_capability & 2 ? "Auto" : "", p->offline_capability & 4 ? "AbortOnCmd" : "SuspendOnCmd"); |
428 | (p->offline_status & 0x80 ? "Yes" : "No"), | 370 | printf(_("SmartRevision=%d, CheckSum=%d, SmartCapability=%d {%s %s}\n"), p->revision, p->checksum, p->smart_capability, |
429 | p->offline_timeout / 60); | 371 | p->smart_capability & 1 ? "SaveOnStandBy" : "", p->smart_capability & 2 ? "AutoSave" : ""); |
430 | printf | ||
431 | (_("OffLineCapability=%d {%s %s %s}\n"), | ||
432 | p->offline_capability, | ||
433 | p->offline_capability & 1 ? "Immediate" : "", | ||
434 | p->offline_capability & 2 ? "Auto" : "", | ||
435 | p->offline_capability & 4 ? "AbortOnCmd" : "SuspendOnCmd"); | ||
436 | printf | ||
437 | (_("SmartRevision=%d, CheckSum=%d, SmartCapability=%d {%s %s}\n"), | ||
438 | p->revision, | ||
439 | p->checksum, | ||
440 | p->smart_capability, | ||
441 | p->smart_capability & 1 ? "SaveOnStandBy" : "", | ||
442 | p->smart_capability & 2 ? "AutoSave" : ""); | ||
443 | } | 372 | } |
444 | 373 | ||
445 | 374 | int smart_cmd_simple(int fd, enum SmartCommand command, uint8_t val0, bool show_error) { | |
446 | int smart_cmd_simple (int fd, enum SmartCommand command, __u8 val0, bool show_error) { | ||
447 | int e = STATE_UNKNOWN; | 375 | int e = STATE_UNKNOWN; |
448 | #ifdef __linux__ | 376 | #ifdef __linux__ |
449 | __u8 args[4]; | 377 | uint8_t args[4]; |
450 | args[0] = WIN_SMART; | 378 | args[0] = WIN_SMART; |
451 | args[1] = val0; | 379 | args[1] = val0; |
452 | args[2] = smart_command[command].value; | 380 | args[2] = smart_command[command].value; |
453 | args[3] = 0; | 381 | args[3] = 0; |
454 | if (ioctl (fd, HDIO_DRIVE_CMD, &args)) { | 382 | if (ioctl(fd, HDIO_DRIVE_CMD, &args)) { |
455 | e = STATE_CRITICAL; | 383 | e = STATE_CRITICAL; |
456 | if (show_error) | 384 | if (show_error) { |
457 | printf (_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror (errno)); | 385 | printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno)); |
386 | } | ||
458 | } else { | 387 | } else { |
459 | e = STATE_OK; | 388 | e = STATE_OK; |
460 | if (show_error) | 389 | if (show_error) { |
461 | printf (_("OK - Command sent (%s)\n"), smart_command[command].text); | 390 | printf(_("OK - Command sent (%s)\n"), smart_command[command].text); |
391 | } | ||
462 | } | 392 | } |
463 | 393 | ||
464 | #endif /* __linux__ */ | 394 | #endif /* __linux__ */ |
@@ -474,44 +404,44 @@ int smart_cmd_simple (int fd, enum SmartCommand command, __u8 val0, bool show_er | |||
474 | req.sec_count = val0; | 404 | req.sec_count = val0; |
475 | 405 | ||
476 | if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { | 406 | if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { |
477 | if (req.retsts != ATACMD_OK) | 407 | if (req.retsts != ATACMD_OK) { |
478 | errno = ENODEV; | 408 | errno = ENODEV; |
479 | if (req.cylinder != WDSMART_CYL) | 409 | } |
410 | if (req.cylinder != WDSMART_CYL) { | ||
480 | errno = ENODEV; | 411 | errno = ENODEV; |
412 | } | ||
481 | } | 413 | } |
482 | 414 | ||
483 | if (errno != 0) { | 415 | if (errno != 0) { |
484 | e = STATE_CRITICAL; | 416 | e = STATE_CRITICAL; |
485 | if (show_error) | 417 | if (show_error) { |
486 | printf (_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror (errno)); | 418 | printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno)); |
419 | } | ||
487 | } else { | 420 | } else { |
488 | e = STATE_OK; | 421 | e = STATE_OK; |
489 | if (show_error) | 422 | if (show_error) { |
490 | printf (_("OK - Command sent (%s)\n"), smart_command[command].text); | 423 | printf(_("OK - Command sent (%s)\n"), smart_command[command].text); |
424 | } | ||
491 | } | 425 | } |
492 | 426 | ||
493 | #endif /* __NetBSD__ */ | 427 | #endif /* __NetBSD__ */ |
494 | return e; | 428 | return e; |
495 | } | 429 | } |
496 | 430 | ||
497 | 431 | int smart_read_thresholds(int fd, thresholds_t *thresholds) { | |
498 | |||
499 | int | ||
500 | smart_read_thresholds (int fd, thresholds_t * thresholds) | ||
501 | { | ||
502 | #ifdef __linux__ | 432 | #ifdef __linux__ |
503 | int e; | 433 | int e; |
504 | __u8 args[4 + 512]; | 434 | uint8_t args[4 + 512]; |
505 | args[0] = WIN_SMART; | 435 | args[0] = WIN_SMART; |
506 | args[1] = 0; | 436 | args[1] = 0; |
507 | args[2] = SMART_READ_THRESHOLDS; | 437 | args[2] = SMART_READ_THRESHOLDS; |
508 | args[3] = 1; | 438 | args[3] = 1; |
509 | if (ioctl (fd, HDIO_DRIVE_CMD, &args)) { | 439 | if (ioctl(fd, HDIO_DRIVE_CMD, &args)) { |
510 | e = errno; | 440 | e = errno; |
511 | printf (_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror (errno)); | 441 | printf(_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror(errno)); |
512 | return e; | 442 | return e; |
513 | } | 443 | } |
514 | memcpy (thresholds, args + 4, 512); | 444 | memcpy(thresholds, args + 4, 512); |
515 | #endif /* __linux__ */ | 445 | #endif /* __linux__ */ |
516 | #ifdef __NetBSD__ | 446 | #ifdef __NetBSD__ |
517 | struct atareq req; | 447 | struct atareq req; |
@@ -529,13 +459,14 @@ smart_read_thresholds (int fd, thresholds_t * thresholds) | |||
529 | req.cylinder = WDSMART_CYL; | 459 | req.cylinder = WDSMART_CYL; |
530 | 460 | ||
531 | if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { | 461 | if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { |
532 | if (req.retsts != ATACMD_OK) | 462 | if (req.retsts != ATACMD_OK) { |
533 | errno = ENODEV; | 463 | errno = ENODEV; |
464 | } | ||
534 | } | 465 | } |
535 | 466 | ||
536 | if (errno != 0) { | 467 | if (errno != 0) { |
537 | int e = errno; | 468 | int e = errno; |
538 | printf (_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror (errno)); | 469 | printf(_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror(errno)); |
539 | return e; | 470 | return e; |
540 | } | 471 | } |
541 | 472 | ||
@@ -544,45 +475,43 @@ smart_read_thresholds (int fd, thresholds_t * thresholds) | |||
544 | return 0; | 475 | return 0; |
545 | } | 476 | } |
546 | 477 | ||
478 | void print_help(void) { | ||
479 | print_revision(progname, NP_VERSION); | ||
547 | 480 | ||
548 | void | 481 | printf("(C) 1999 Ragnar Hojland Espinosa <ragnar@lightside.dhis.org>\n"); |
549 | print_help (void) | 482 | printf("Plugin implementation - 1999 Robert Dale <rdale@digital-mission.com>\n"); |
550 | { | 483 | printf(COPYRIGHT, copyright, email); |
551 | print_revision (progname, NP_VERSION); | ||
552 | |||
553 | printf ("(C) 1999 Ragnar Hojland Espinosa <ragnar@lightside.dhis.org>\n"); | ||
554 | printf ("Plugin implementation - 1999 Robert Dale <rdale@digital-mission.com>\n"); | ||
555 | printf (COPYRIGHT, copyright, email); | ||
556 | 484 | ||
557 | printf (_("This plugin checks a local hard drive with the (Linux specific) SMART interface [http://smartlinux.sourceforge.net/smart/index.php].")); | 485 | printf(_("This plugin checks a local hard drive with the (Linux specific) SMART interface " |
486 | "[http://smartlinux.sourceforge.net/smart/index.php].")); | ||
558 | 487 | ||
559 | printf ("\n\n"); | 488 | printf("\n\n"); |
560 | 489 | ||
561 | print_usage (); | 490 | print_usage(); |
562 | 491 | ||
563 | printf (UT_HELP_VRSN); | 492 | printf(UT_HELP_VRSN); |
564 | printf (UT_EXTRA_OPTS); | 493 | printf(UT_EXTRA_OPTS); |
565 | 494 | ||
566 | printf (" %s\n", "-d, --device=DEVICE"); | 495 | printf(" %s\n", "-d, --device=DEVICE"); |
567 | printf (" %s\n", _("Select device DEVICE")); | 496 | printf(" %s\n", _("Select device DEVICE")); |
568 | printf (" %s\n", _("Note: if the device is specified without this option, any further option will")); | 497 | printf(" %s\n", _("Note: if the device is specified without this option, any further option will")); |
569 | printf (" %s\n", _("be ignored.")); | 498 | printf(" %s\n", _("be ignored.")); |
570 | 499 | ||
571 | printf (UT_VERBOSE); | 500 | printf(UT_VERBOSE); |
572 | 501 | ||
573 | printf ("\n"); | 502 | printf("\n"); |
574 | printf ("%s\n", _("Notes:")); | 503 | printf("%s\n", _("Notes:")); |
575 | printf (" %s\n", _("The SMART command modes (-i/--immediate, -0/--auto-off and -1/--auto-on) were")); | 504 | printf(" %s\n", _("The SMART command modes (-i/--immediate, -0/--auto-off and -1/--auto-on) were")); |
576 | printf (" %s\n", _("broken in an underhand manner and have been disabled. You can use smartctl")); | 505 | printf(" %s\n", _("broken in an underhand manner and have been disabled. You can use smartctl")); |
577 | printf (" %s\n", _("instead:")); | 506 | printf(" %s\n", _("instead:")); |
578 | printf (" %s\n", _("-0/--auto-off: use \"smartctl --offlineauto=off\"")); | 507 | printf(" %s\n", _("-0/--auto-off: use \"smartctl --offlineauto=off\"")); |
579 | printf (" %s\n", _("-1/--auto-on: use \"smartctl --offlineauto=on\"")); | 508 | printf(" %s\n", _("-1/--auto-on: use \"smartctl --offlineauto=on\"")); |
580 | printf (" %s\n", _("-i/--immediate: use \"smartctl --test=offline\"")); | 509 | printf(" %s\n", _("-i/--immediate: use \"smartctl --test=offline\"")); |
581 | 510 | ||
582 | printf (UT_SUPPORT); | 511 | printf(UT_SUPPORT); |
583 | } | 512 | } |
584 | 513 | ||
585 | /* todo : add to the long nanual as example | 514 | /* todo : add to the long nanual as example |
586 | * | 515 | * |
587 | * Run with: check_ide-smart --nagios [-d] <DRIVE> | 516 | * Run with: check_ide-smart --nagios [-d] <DRIVE> |
588 | * Where DRIVE is an IDE drive, ie. /dev/hda, /dev/hdb, /dev/hdc | 517 | * Where DRIVE is an IDE drive, ie. /dev/hda, /dev/hdb, /dev/hdc |
@@ -593,10 +522,7 @@ print_help (void) | |||
593 | * - Returns -1 not too often | 522 | * - Returns -1 not too often |
594 | */ | 523 | */ |
595 | 524 | ||
596 | 525 | void print_usage(void) { | |
597 | void | 526 | printf("%s\n", _("Usage:")); |
598 | print_usage (void) | 527 | printf("%s [-d <device>] [-v]", progname); |
599 | { | ||
600 | printf ("%s\n", _("Usage:")); | ||
601 | printf ("%s [-d <device>] [-v]", progname); | ||
602 | } | 528 | } |