2 * check_ide-smart v.1 - hacked version of ide-smart for Nagios
3 * Copyright (C) 2000 Robert Dale <rdale@digital-mission.com>
5 * Nagios - http://www.nagios.org
8 * ide-smart has the same functionality as before. Some return
9 * values were changed, otherwise the --nagios option was added.
11 * Run with: check_ide-smart --nagios [-d] <DRIVE>
12 * Where DRIVE is an IDE drive, ie. /dev/hda, /dev/hdb, /dev/hdc
14 * - Returns 0 on no errors
15 * - Returns 1 on advisories
16 * - Returns 2 on prefailure
17 * - Returns -1 not too often
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>
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.
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.
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.
40 const char *progname
= "check_ide_smart";
41 const char *revision
= "$Revision$";
42 const char *copyright
= "2000-2004";
43 const char *email
= "nagiosplug-devel@lists.sourceforge.net";
48 void print_help (void);
49 void print_usage (void);
52 #include <sys/ioctl.h>
54 #include <linux/hdreg.h>
55 #include <linux/types.h>
58 #define NR_ATTRIBUTES 30
69 typedef struct threshold_s
75 __attribute__ ((packed
)) threshold_t
;
77 typedef struct thresholds_s
80 threshold_t thresholds
[NR_ATTRIBUTES
];
85 __attribute__ ((packed
)) thresholds_t
;
87 typedef struct value_s
94 __attribute__ ((packed
)) value_t
;
96 typedef struct values_s
99 value_t values
[NR_ATTRIBUTES
];
102 __u16 offline_timeout
;
104 __u8 offline_capability
;
105 __u16 smart_capability
;
110 __attribute__ ((packed
)) values_t
;
118 offline_status_text
[] =
120 {0x00, "NeverStarted"},
136 {SMART_ENABLE
, "SMART_ENABLE"},
137 {SMART_DISABLE
, "SMART_DISABLE"},
138 {SMART_IMMEDIATE_OFFLINE
, "SMART_IMMEDIATE_OFFLINE"},
139 {SMART_AUTO_OFFLINE
, "SMART_AUTO_OFFLINE"}
143 /* Index to smart_command table, keep in order */
147 SMART_CMD_IMMEDIATE_OFFLINE
,
148 SMART_CMD_AUTO_OFFLINE
151 void print_values (values_t
* p
, thresholds_t
* t
);
152 int smart_cmd_simple (int fd
, enum SmartCommand command
, __u8 val0
, char show_error
);
155 main (int argc
, char *argv
[])
162 thresholds_t thresholds
;
166 static struct option longopts
[] = {
167 {"device", required_argument
, 0, 'd'},
168 {"immediate", no_argument
, 0, 'i'},
169 {"quiet-check", no_argument
, 0, 'q'},
170 {"auto-on", no_argument
, 0, '1'},
171 {"auto-off", no_argument
, 0, '0'},
172 {"nagios", no_argument
, 0, 'n'},
173 {"help", no_argument
, 0, 'h'},
174 {"version", no_argument
, 0, 'V'}, {0, 0, 0, 0}
177 setlocale (LC_ALL
, "");
178 bindtextdomain (PACKAGE
, LOCALEDIR
);
179 textdomain (PACKAGE
);
183 o
= getopt_long (argc
, argv
, "+d:iq10nhV", longopts
, &longindex
);
185 if (o
== -1 || o
== EOF
|| o
== 1)
211 print_revision (progname
, revision
);
214 usage2 (_("Unknown argument"), optarg
);
219 device
= argv
[optind
];
227 fd
= open (device
, O_RDONLY
);
230 printf (_("CRITICAL - Couldn't open device %s: %s\n"), device
, strerror (errno
));
231 return STATE_CRITICAL
;
234 if (smart_cmd_simple (fd
, SMART_CMD_ENABLE
, 0, TRUE
)) {
235 printf (_("CRITICAL - SMART_CMD_ENABLE\n"));
236 return STATE_CRITICAL
;
241 retval
= smart_cmd_simple (fd
, SMART_CMD_AUTO_OFFLINE
, 0, TRUE
);
244 retval
= smart_cmd_simple (fd
, SMART_CMD_AUTO_OFFLINE
, 0xF8, TRUE
);
247 retval
= smart_cmd_simple (fd
, SMART_CMD_IMMEDIATE_OFFLINE
, 0, TRUE
);
250 smart_read_values (fd
, &values
);
251 smart_read_thresholds (fd
, &thresholds
);
252 retval
= values_not_passed (&values
, &thresholds
);
255 smart_read_values (fd
, &values
);
256 smart_read_thresholds (fd
, &thresholds
);
257 retval
= nagios (&values
, &thresholds
);
260 smart_read_values (fd
, &values
);
261 smart_read_thresholds (fd
, &thresholds
);
262 print_values (&values
, &thresholds
);
272 get_offline_text (int status
)
275 for (i
= 0; offline_status_text
[i
].text
; i
++) {
276 if (offline_status_text
[i
].value
== status
) {
277 return offline_status_text
[i
].text
;
286 smart_read_values (int fd
, values_t
* values
)
292 args
[2] = SMART_READ_VALUES
;
294 if (ioctl (fd
, HDIO_DRIVE_CMD
, &args
)) {
296 printf (_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror (errno
));
299 memcpy (values
, args
+ 4, 512);
306 values_not_passed (values_t
* p
, thresholds_t
* t
)
308 value_t
* value
= p
->values
;
309 threshold_t
* threshold
= t
->thresholds
;
313 for (i
= 0; i
< NR_ATTRIBUTES
; i
++) {
314 if (value
->id
&& threshold
->id
&& value
->id
== threshold
->id
) {
315 if (value
->value
<= threshold
->threshold
) {
325 return (passed
? -failed
: 2);
331 nagios (values_t
* p
, thresholds_t
* t
)
333 value_t
* value
= p
->values
;
334 threshold_t
* threshold
= t
->thresholds
;
335 int status
= OPERATIONAL
;
342 for (i
= 0; i
< NR_ATTRIBUTES
; i
++) {
343 if (value
->id
&& threshold
->id
&& value
->id
== threshold
->id
) {
344 if (value
->value
<= threshold
->threshold
) {
346 if (value
->status
& 1) {
365 printf (_("CRITICAL - %d Harddrive PreFailure%cDetected! %d/%d tests failed.\n"),
367 prefailure
> 1 ? 's' : ' ',
370 status
=STATE_CRITICAL
;
373 printf (_("WARNING - %d Harddrive Advisor%s Detected. %d/%d tests failed.\n"),
375 advisory
> 1 ? "ies" : "y",
378 status
=STATE_WARNING
;
381 printf (_("OK - Operational (%d/%d tests passed)\n"), passed
, total
);
385 printf (_("ERROR - Status '%d' unkown. %d/%d tests passed\n"), status
,
387 status
= STATE_UNKNOWN
;
396 print_value (value_t
* p
, threshold_t
* t
)
398 printf ("Id=%3d, Status=%2d {%s , %s}, Value=%3d, Threshold=%3d, %s\n",
399 p
->id
, p
->status
, p
->status
& 1 ? "PreFailure" : "Advisory ",
400 p
->status
& 2 ? "OnLine " : "OffLine", p
->value
, t
->threshold
,
401 p
->value
> t
->threshold
? "Passed" : "Failed");
407 print_values (values_t
* p
, thresholds_t
* t
)
409 value_t
* value
= p
->values
;
410 threshold_t
* threshold
= t
->thresholds
;
412 for (i
= 0; i
< NR_ATTRIBUTES
; i
++) {
413 if (value
->id
&& threshold
->id
&& value
->id
== threshold
->id
) {
414 print_value (value
++, threshold
++);
418 (_("OffLineStatus=%d {%s}, AutoOffLine=%s, OffLineTimeout=%d minutes\n"),
420 get_offline_text (p
->offline_status
& 0x7f),
421 (p
->offline_status
& 0x80 ? "Yes" : "No"),
422 p
->offline_timeout
/ 60);
424 (_("OffLineCapability=%d {%s %s %s}\n"),
425 p
->offline_capability
,
426 p
->offline_capability
& 1 ? "Immediate" : "",
427 p
->offline_capability
& 2 ? "Auto" : "",
428 p
->offline_capability
& 4 ? "AbortOnCmd" : "SuspendOnCmd");
430 (_("SmartRevision=%d, CheckSum=%d, SmartCapability=%d {%s %s}\n"),
434 p
->smart_capability
& 1 ? "SaveOnStandBy" : "",
435 p
->smart_capability
& 2 ? "AutoSave" : "");
441 print_thresholds (thresholds_t
* p
)
443 threshold_t
* threshold
= p
->thresholds
;
446 printf ("SmartRevision=%d\n", p
->revision
);
447 for (i
= 0; i
< NR_ATTRIBUTES
; i
++) {
449 printf ("Id=%3d, Threshold=%3d\n", threshold
->id
,
450 threshold
->threshold
); }
453 printf ("CheckSum=%d\n", p
->checksum
);
457 smart_cmd_simple (int fd
, enum SmartCommand command
, __u8 val0
, char show_error
)
463 args
[2] = smart_command
[command
].value
;
465 if (ioctl (fd
, HDIO_DRIVE_CMD
, &args
)) {
468 printf (_("CRITICAL - %s: %s\n"), smart_command
[command
].text
, strerror (errno
));
477 smart_read_thresholds (int fd
, thresholds_t
* thresholds
)
483 args
[2] = SMART_READ_THRESHOLDS
;
485 if (ioctl (fd
, HDIO_DRIVE_CMD
, &args
)) {
487 printf (_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror (errno
));
490 memcpy (thresholds
, args
+ 4, 512);
498 print_revision (progname
, revision
);
500 printf ("Nagios feature - 1999 Robert Dale <rdale@digital-mission.com>\n");
501 printf ("(C) 1999 Ragnar Hojland Espinosa <ragnar@lightside.dhis.org>\n");
502 printf (COPYRIGHT
, copyright
, email
);
504 printf(_("This plugin checks a local hard drive with the (Linux specific) SMART interface [http://smartlinux.sourceforge.net/smart/index.php].\n\n"));
507 Usage: %s [OPTION] [DEVICE]\n\
508 -d, --device=DEVICE\n\
509 Select device DEVICE\n\
510 Note: if the device is selected with this option, _no_ other options are accepted\n\
512 Perform immediately offline tests\n\
514 Returns the number of failed tests\n\
516 Turn on automatic offline tests\n\
518 Turn off automatic offline tests\n\
520 Output suitable for Nagios\n", progname
);
528 Usage: %s [-d <device>] [-i <immediate>] [-q quiet] [-1 <auto-on>]\n\
529 [-O <auto-off>] [-n <nagios>]\n", progname
);