summaryrefslogtreecommitdiffstats
path: root/plugins/check_ide-smart.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_ide-smart.c')
-rw-r--r--plugins/check_ide-smart.c523
1 files changed, 0 insertions, 523 deletions
diff --git a/plugins/check_ide-smart.c b/plugins/check_ide-smart.c
deleted file mode 100644
index 1c0af310..00000000
--- a/plugins/check_ide-smart.c
+++ /dev/null
@@ -1,523 +0,0 @@
1/*
2 * check_ide-smart v.1 - hacked version of ide-smart for Nagios
3 * Copyright (C) 2000 Robert Dale <rdale@digital-mission.com>
4 *
5 * Nagios - http://www.nagios.org
6 *
7 * Notes:
8 * ide-smart has the same functionality as before. Some return
9 * values were changed, otherwise the --net-saint option was added.
10 *
11 * Run with: check_ide-smart --net-saint [-d] <DRIVE>
12 * Where DRIVE is an IDE drive, ie. /dev/hda, /dev/hdb, /dev/hdc
13 *
14 * - Returns 0 on no errors
15 * - Returns 1 on advisories
16 * - Returns 2 on prefailure
17 * - Returns -1 not too often
18 *
19 * ide-smart 1.3 - IDE S.M.A.R.T. checking tool
20 * Copyright (C) 1998-1999 Ragnar Hojland Espinosa <ragnar@lightside.dhis.org>
21 * 1998 Gadi Oxman <gadio@netvision.net.il>
22 *
23 * This program is free software; you can redistribute it and/or modify
24 * it under the terms of the GNU General Public License as published by
25 * the Free Software Foundation; either version 2 of the License, or
26 * (at your option) any later version.
27 *
28 * This program is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
32 *
33 * You should have received a copy of the GNU General Public License
34 * along with this program; if not, write to the Free Software
35 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
36 *
37 * $Id$
38 */
39
40const char *progname = "check_ide_smart";
41const char *revision = "$Revision$";
42const char *copyright = "2000-2004";
43const char *email = "nagiosplug-devel@lists.sourceforge.net";
44
45#include "common.h"
46#include "utils.h"
47
48#include <sys/stat.h>
49#include <sys/ioctl.h>
50#include <fcntl.h>
51#include <linux/hdreg.h>
52#include <linux/types.h>
53#include <errno.h>
54
55#define NR_ATTRIBUTES 30
56
57#ifndef TRUE
58#define TRUE 1
59#endif /* */
60
61#define PREFAILURE 2
62#define ADVISORY 1
63#define OPERATIONAL 0
64#define UNKNOWN -1
65
66typedef struct threshold_s
67{
68 __u8 id;
69 __u8 threshold;
70 __u8 reserved[10];
71}
72__attribute__ ((packed)) threshold_t;
73
74typedef struct thresholds_s
75{
76 __u16 revision;
77 threshold_t thresholds[NR_ATTRIBUTES];
78 __u8 reserved[18];
79 __u8 vendor[131];
80 __u8 checksum;
81}
82__attribute__ ((packed)) thresholds_t;
83
84typedef struct value_s
85{
86 __u8 id;
87 __u16 status;
88 __u8 value;
89 __u8 vendor[8];
90}
91__attribute__ ((packed)) value_t;
92
93typedef struct values_s
94{
95 __u16 revision;
96 value_t values[NR_ATTRIBUTES];
97 __u8 offline_status;
98 __u8 vendor1;
99 __u16 offline_timeout;
100 __u8 vendor2;
101 __u8 offline_capability;
102 __u16 smart_capability;
103 __u8 reserved[16];
104 __u8 vendor[125];
105 __u8 checksum;
106}
107__attribute__ ((packed)) values_t;
108
109struct
110{
111 __u8 value;
112 char *text;
113}
114
115offline_status_text[] =
116 {
117 {0x00, "NeverStarted"},
118 {0x02, "Completed"},
119 {0x04, "Suspended"},
120 {0x05, "Aborted"},
121 {0x06, "Failed"},
122 {0, 0}
123 };
124
125struct
126{
127 __u8 value;
128 char *text;
129}
130
131smart_command[] =
132 {
133 {SMART_ENABLE, "SMART_ENABLE"},
134 {SMART_DISABLE, "SMART_DISABLE"},
135 {SMART_IMMEDIATE_OFFLINE, "SMART_IMMEDIATE_OFFLINE"},
136 {SMART_AUTO_OFFLINE, "SMART_AUTO_OFFLINE"}
137 };
138
139
140/* Index to smart_command table, keep in order */
141enum SmartCommand
142 { SMART_CMD_ENABLE,
143 SMART_CMD_DISABLE,
144 SMART_CMD_IMMEDIATE_OFFLINE,
145 SMART_CMD_AUTO_OFFLINE
146 };
147
148
149int
150main (int argc, char *argv[])
151{
152 char *device = NULL;
153 int command = -1;
154 int o, longindex;
155 int retval = 0;
156
157 thresholds_t thresholds;
158 values_t values;
159 int fd;
160
161 static struct option longopts[] = {
162 {"device", required_argument, 0, 'd'},
163 {"immediate", no_argument, 0, 'i'},
164 {"quiet-check", no_argument, 0, 'q'},
165 {"auto-on", no_argument, 0, '1'},
166 {"auto-off", no_argument, 0, '0'},
167 {"net-saint", no_argument, 0, 'n'},
168 {"help", no_argument, 0, 'h'},
169 {"version", no_argument, 0, 'V'}, {0, 0, 0, 0}
170 };
171
172 setlocale (LC_ALL, "");
173 bindtextdomain (PACKAGE, LOCALEDIR);
174 textdomain (PACKAGE);
175
176 while (1) {
177
178 o = getopt_long (argc, argv, "+d:iq10nhV", longopts, &longindex);
179
180 if (o == -1 || o == EOF)
181 break;
182
183 switch (o) {
184 case 'd':
185 device = optarg;
186 break;
187 case 'q':
188 command = 3;
189 break;
190 case 'i':
191 command = 2;
192 break;
193 case '1':
194 command = 1;
195 break;
196 case '0':
197 command = 0;
198 break;
199 case 'n':
200 command = 4;
201 break;
202 case 'h':
203 print_help ();
204 return STATE_OK;
205 case 'V':
206 print_revision (progname, revision);
207 return STATE_OK;
208 default:
209 printf (_("%s: Unknown argument: %s\n\n"), progname, optarg);
210 print_usage ();
211 exit (STATE_UNKNOWN);
212 }
213
214 if (optind < argc) {
215 device = argv[optind];
216 }
217
218 if (!device) {
219 show_help ();
220 show_version ();
221 return -1;
222 }
223
224 fd = open (device, O_RDONLY);
225
226 if (fd < 0) {
227 printf (_("CRITICAL - Couldn't open device: %s\n"), strerror (errno));
228 return 2;
229 }
230
231 if (smart_cmd_simple (fd, SMART_CMD_ENABLE, 0, TRUE)) {
232 printf (_("CRITICAL - SMART_CMD_ENABLE\n"));
233 return 2;
234 }
235
236 switch (command) {
237 case 0:
238 retval = smart_cmd_simple (fd, SMART_CMD_AUTO_OFFLINE, 0, TRUE);
239 break;
240 case 1:
241 retval = smart_cmd_simple (fd, SMART_CMD_AUTO_OFFLINE, 0xF8, TRUE);
242 break;
243 case 2:
244 retval = smart_cmd_simple (fd, SMART_CMD_IMMEDIATE_OFFLINE, 0, TRUE);
245 break;
246 case 3:
247 smart_read_values (fd, &values);
248 smart_read_thresholds (fd, &thresholds);
249 retval = values_not_passed (&values, &thresholds);
250 break;
251 case 4:
252 smart_read_values (fd, &values);
253 smart_read_thresholds (fd, &thresholds);
254 retval = net_saint (&values, &thresholds);
255 break;
256 default:
257 smart_read_values (fd, &values);
258 smart_read_thresholds (fd, &thresholds);
259 print_values (&values, &thresholds);
260 break;
261 }
262 close (fd);
263 }
264 return retval;
265}
266
267
268
269char *
270get_offline_text (int status)
271{
272 int i;
273 for (i = 0; offline_status_text[i].text; i++) {
274 if (offline_status_text[i].value == status) {
275 return offline_status_text[i].text;
276 }
277 }
278 return "UNKNOW";
279}
280
281
282
283int
284smart_read_values (int fd, values_t * values)
285{
286 int e;
287 __u8 args[4 + 512];
288 args[0] = WIN_SMART;
289 args[1] = 0;
290 args[2] = SMART_READ_VALUES;
291 args[3] = 1;
292 if (ioctl (fd, HDIO_DRIVE_CMD, &args)) {
293 e = errno;
294 printf (_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror (errno));
295 return e;
296 }
297 memcpy (values, args + 4, 512);
298 return 0;
299}
300
301
302
303int
304values_not_passed (values_t * p, thresholds_t * t)
305{
306 value_t * value = p->values;
307 threshold_t * threshold = t->thresholds;
308 int failed = 0;
309 int passed = 0;
310 int i;
311 for (i = 0; i < NR_ATTRIBUTES; i++) {
312 if (value->id && threshold->id && value->id == threshold->id) {
313 if (value->value <= threshold->threshold) {
314 ++failed;
315 }
316 else {
317 ++passed;
318 }
319 }
320 ++value;
321 ++threshold;
322 }
323 return (passed ? -failed : 2);
324}
325
326
327
328int
329net_saint (values_t * p, thresholds_t * t)
330{
331 value_t * value = p->values;
332 threshold_t * threshold = t->thresholds;
333 int status = OPERATIONAL;
334 int prefailure = 0;
335 int advisory = 0;
336 int failed = 0;
337 int passed = 0;
338 int total = 0;
339 int i;
340 for (i = 0; i < NR_ATTRIBUTES; i++) {
341 if (value->id && threshold->id && value->id == threshold->id) {
342 if (value->value <= threshold->threshold) {
343 ++failed;
344 if (value->status & 1) {
345 status = PREFAILURE;
346 ++prefailure;
347 }
348 else {
349 status = ADVISORY;
350 ++advisory;
351 }
352 }
353 else {
354 ++passed;
355 }
356 ++total;
357 }
358 ++value;
359 ++threshold;
360 }
361 switch (status) {
362 case PREFAILURE:
363 printf (_("CRITICAL - %d Harddrive PreFailure%cDetected! %d/%d tests failed.\n"),
364 prefailure,
365 prefailure > 1 ? 's' : ' ',
366 failed,
367 total);
368 break;
369 case ADVISORY:
370 printf (_("WARNING - %d Harddrive Advisor%s Detected. %d/%d tests failed.\n"),
371 advisory,
372 advisory > 1 ? "ies" : "y",
373 failed,
374 total);
375 break;
376 case OPERATIONAL:
377 printf (_("OK - Operational (%d/%d tests passed)\n"), passed, total);
378 break;
379 default:
380 printf (_("ERROR - Status '%d' uknown. %d/%d tests passed\n"), status,
381 passed, total);
382 status = -1;
383 break;
384 }
385 return status;
386}
387
388
389
390void
391print_value (value_t * p, threshold_t * t)
392{
393 printf ("Id=%3d, Status=%2d {%s , %s}, Value=%3d, Threshold=%3d, %s\n",
394 p->id, p->status, p->status & 1 ? "PreFailure" : "Advisory ",
395 p->status & 2 ? "OnLine " : "OffLine", p->value, t->threshold,
396 p->value > t->threshold ? "Passed" : "Failed");
397}
398
399
400
401void
402print_values (values_t * p, thresholds_t * t)
403{
404 value_t * value = p->values;
405 threshold_t * threshold = t->thresholds;
406 int i;
407 for (i = 0; i < NR_ATTRIBUTES; i++) {
408 if (value->id && threshold->id && value->id == threshold->id) {
409 print_value (value++, threshold++);
410 }
411 }
412 printf
413 (_("OffLineStatus=%d {%s}, AutoOffLine=%s, OffLineTimeout=%d minutes\n"),
414 p->offline_status,
415 get_offline_text (p->offline_status & 0x7f),
416 (p->offline_status & 0x80 ? "Yes" : "No"),
417 p->offline_timeout / 60);
418 printf
419 (_("OffLineCapability=%d {%s %s %s}\n"),
420 p->offline_capability,
421 p->offline_capability & 1 ? "Immediate" : "",
422 p->offline_capability & 2 ? "Auto" : "",
423 p->offline_capability & 4 ? "AbortOnCmd" : "SuspendOnCmd");
424 printf
425 (_("SmartRevision=%d, CheckSum=%d, SmartCapability=%d {%s %s}\n"),
426 p->revision,
427 p->checksum,
428 p->smart_capability,
429 p->smart_capability & 1 ? "SaveOnStandBy" : "",
430 p->smart_capability & 2 ? "AutoSave" : "");
431}
432
433
434
435void
436print_thresholds (thresholds_t * p)
437{
438 threshold_t * threshold = p->thresholds;
439 int i;
440 printf ("\n");
441 printf ("SmartRevision=%d\n", p->revision);
442 for (i = 0; i < NR_ATTRIBUTES; i++) {
443 if (threshold->id) {
444 printf ("Id=%3d, Threshold=%3d\n", threshold->id,
445 threshold->threshold); }
446 ++threshold;
447 }
448 printf ("CheckSum=%d\n", p->checksum);
449}
450
451int
452smart_cmd_simple (int fd, enum SmartCommand command, __u8 val0,
453 char show_error)
454{
455 int e = 0;
456 __u8 args[4];
457 args[0] = WIN_SMART;
458 args[1] = val0;
459 args[2] = smart_command[command].value;
460 args[3] = 0;
461 if (ioctl (fd, HDIO_DRIVE_CMD, &args)) {
462 e = errno;
463 if (show_error) {
464 printf (_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror (errno));
465 }
466 }
467 return e;
468}
469
470
471
472int
473smart_read_thresholds (int fd, thresholds_t * thresholds)
474{
475 int e;
476 __u8 args[4 + 512];
477 args[0] = WIN_SMART;
478 args[1] = 0;
479 args[2] = SMART_READ_THRESHOLDS;
480 args[3] = 1;
481 if (ioctl (fd, HDIO_DRIVE_CMD, &args)) {
482 e = errno;
483 printf (_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror (errno));
484 return e;
485 }
486 memcpy (thresholds, args + 4, 512);
487 return 0;
488}
489
490
491
492void
493print_help ()
494{
495 print_revision (progname, revision);
496
497 printf ("Nagios feature - 1999 Robert Dale <rdale@digital-mission.com>\n");
498 printf ("(C) 1999 Ragnar Hojland Espinosa <ragnar@lightside.dhis.org>\n");
499 printf (COPYRIGHT, copyright, email);
500
501 printf (_("\
502Usage: %s [DEVICE] [OPTION]\n\
503 -d, --device=DEVICE\n\
504 Select device DEVICE\n\
505 -i, --immediate\n\
506 Perform immediately offline tests\n\
507 -q, --quiet-check\n\
508 Returns the number of failed tests\n\
509 -1, --auto-on\n\
510 Turn on automatic offline tests\n\
511 -0, --auto-off\n\
512 Turn off automatic offline tests\n\
513 -n, --net-saint\n\
514 Output suitable for Net Saint\n", progname);
515}
516
517
518
519void
520print_usage (void)
521{
522 printf ("Usage: %s \n"), progname);
523}