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.c302
1 files changed, 175 insertions, 127 deletions
diff --git a/plugins/check_ide-smart.c b/plugins/check_ide-smart.c
index 47d9d84..ecd8a4e 100644
--- a/plugins/check_ide-smart.c
+++ b/plugins/check_ide-smart.c
@@ -16,7 +16,7 @@
16 * - Returns 2 on prefailure 16 * - Returns 2 on prefailure
17 * - Returns -1 not too often 17 * - Returns -1 not too often
18 * 18 *
19 * ide-smart 1.3 - IDE S.M.A.R.T. cheking tool 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> 20 * Copyright (C) 1998-1999 Ragnar Hojland Espinosa <ragnar@lightside.dhis.org>
21 * 1998 Gadi Oxman <gadio@netvision.net.il> 21 * 1998 Gadi Oxman <gadio@netvision.net.il>
22 * 22 *
@@ -33,15 +33,13 @@
33 * You should have received a copy of the GNU General Public License 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 34 * along with this program; if not, write to the Free Software
35 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 35 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
36 */ 36 */
37 37
38#include <stdio.h> 38#include "common.h"
39#include <sys/types.h> 39#include "utils.h"
40#include <sys/stat.h> 40#include <sys/stat.h>
41#include <sys/ioctl.h> 41#include <sys/ioctl.h>
42#include <fcntl.h> 42#include <fcntl.h>
43#include <string.h>
44#include <unistd.h>
45#include <linux/hdreg.h> 43#include <linux/hdreg.h>
46#include <linux/types.h> 44#include <linux/types.h>
47#include <errno.h> 45#include <errno.h>
@@ -56,13 +54,15 @@
56#define ADVISORY 1 54#define ADVISORY 1
57#define OPERATIONAL 0 55#define OPERATIONAL 0
58#define UNKNOWN -1 56#define UNKNOWN -1
59 typedef struct threshold_s 57
58typedef struct threshold_s
60{ 59{
61 __u8 id; 60 __u8 id;
62 __u8 threshold; 61 __u8 threshold;
63 __u8 reserved[10]; 62 __u8 reserved[10];
64} 63}
65__attribute__ ((packed)) threshold_t; 64__attribute__ ((packed)) threshold_t;
65
66typedef struct thresholds_s 66typedef struct thresholds_s
67{ 67{
68 __u16 revision; 68 __u16 revision;
@@ -72,6 +72,7 @@ typedef struct thresholds_s
72 __u8 checksum; 72 __u8 checksum;
73} 73}
74__attribute__ ((packed)) thresholds_t; 74__attribute__ ((packed)) thresholds_t;
75
75typedef struct value_s 76typedef struct value_s
76{ 77{
77 __u8 id; 78 __u8 id;
@@ -80,6 +81,7 @@ typedef struct value_s
80 __u8 vendor[8]; 81 __u8 vendor[8];
81} 82}
82__attribute__ ((packed)) value_t; 83__attribute__ ((packed)) value_t;
84
83typedef struct values_s 85typedef struct values_s
84{ 86{
85 __u16 revision; 87 __u16 revision;
@@ -95,49 +97,46 @@ typedef struct values_s
95 __u8 checksum; 97 __u8 checksum;
96} 98}
97__attribute__ ((packed)) values_t; 99__attribute__ ((packed)) values_t;
100
98struct 101struct
99{ 102{
100 __u8 value; 103 __u8 value;
101 char *text; 104 char *text;
102 } 105}
106
103offline_status_text[] = 107offline_status_text[] =
104{ 108 {
105 { 109 {0x00, "NeverStarted"},
106 0x00, "NeverStarted"} 110 {0x02, "Completed"},
107 , { 111 {0x04, "Suspended"},
108 0x02, "Completed"} 112 {0x05, "Aborted"},
109 , { 113 {0x06, "Failed"},
110 0x04, "Suspended"} 114 {0, 0}
111 , { 115 };
112 0x05, "Aborted"} 116
113 , {
114 0x06, "Failed"}
115 , {
116 0, 0}
117};
118struct 117struct
119{ 118{
120 __u8 value; 119 __u8 value;
121 char *text; 120 char *text;
122 } 121}
122
123smart_command[] = 123smart_command[] =
124{ 124 {
125 { 125 {SMART_ENABLE, "SMART_ENABLE"},
126 SMART_ENABLE, "SMART_ENABLE"} 126 {SMART_DISABLE, "SMART_DISABLE"},
127 , { 127 {SMART_IMMEDIATE_OFFLINE, "SMART_IMMEDIATE_OFFLINE"},
128 SMART_DISABLE, "SMART_DISABLE"} 128 {SMART_AUTO_OFFLINE, "SMART_AUTO_OFFLINE"}
129 , { 129 };
130 SMART_IMMEDIATE_OFFLINE, "SMART_IMMEDIATE_OFFLINE"}
131 , {
132 SMART_AUTO_OFFLINE, "SMART_AUTO_OFFLINE"}
133, };
134 130
135 131
136/* Index to smart_command table, keep in order */ 132/* Index to smart_command table, keep in order */
137enum SmartCommand 133enum SmartCommand
138{ SMART_CMD_ENABLE, SMART_CMD_DISABLE, SMART_CMD_IMMEDIATE_OFFLINE, 134 { SMART_CMD_ENABLE,
135 SMART_CMD_DISABLE,
136 SMART_CMD_IMMEDIATE_OFFLINE,
139 SMART_CMD_AUTO_OFFLINE 137 SMART_CMD_AUTO_OFFLINE
140}; 138 };
139
141char * 140char *
142get_offline_text (int status) 141get_offline_text (int status)
143{ 142{
@@ -149,19 +148,25 @@ get_offline_text (int status)
149 } 148 }
150 return "unknown"; 149 return "unknown";
151} 150}
151
152int 152int
153smart_read_values (int fd, values_t * values) 153smart_read_values (int fd, values_t * values)
154{ 154{
155 __u8 args[4 + 512] = { 155 int e;
156 WIN_SMART, 0, SMART_READ_VALUES, 1,}; 156 __u8 args[4 + 512];
157 args[0] = WIN_SMART;
158 args[1] = 0;
159 args[2] = SMART_READ_VALUES;
160 args[3] = 1;
157 if (ioctl (fd, HDIO_DRIVE_CMD, &args)) { 161 if (ioctl (fd, HDIO_DRIVE_CMD, &args)) {
158 int e = errno; 162 e = errno;
159 printf ("Critical: SMART_READ_VALUES: %s\n", strerror (errno)); 163 printf (_("Critical: SMART_READ_VALUES: %s\n"), strerror (errno));
160 return e; 164 return e;
161 } 165 }
162 memcpy (values, args + 4, 512); 166 memcpy (values, args + 4, 512);
163 return 0; 167 return 0;
164} 168}
169
165int 170int
166values_not_passed (values_t * p, thresholds_t * t) 171values_not_passed (values_t * p, thresholds_t * t)
167{ 172{
@@ -184,6 +189,7 @@ values_not_passed (values_t * p, thresholds_t * t)
184 } 189 }
185 return (passed ? -failed : 2); 190 return (passed ? -failed : 2);
186} 191}
192
187int 193int
188net_saint (values_t * p, thresholds_t * t) 194net_saint (values_t * p, thresholds_t * t)
189{ 195{
@@ -219,34 +225,40 @@ net_saint (values_t * p, thresholds_t * t)
219 } 225 }
220 switch (status) { 226 switch (status) {
221 case PREFAILURE: 227 case PREFAILURE:
222 printf ("Critical: %d Harddrive PreFailure%cDetected! " 228 printf (_("Critical: %d Harddrive PreFailure%cDetected! %d/%d tests failed.\n"),
223 "%d/%d tests failed.\n", prefailure, prefailure > 1 ? 's' : ' ', 229 prefailure,
224 failed, total); 230 prefailure > 1 ? 's' : ' ',
231 failed,
232 total);
225 break; 233 break;
226 case ADVISORY: 234 case ADVISORY:
227 printf ("Warning: %d Harddrive Advisor%s Detected. " 235 printf (_("Warning: %d Harddrive Advisor%s Detected. %d/%d tests failed.\n"),
228 "%d/%d tests failed.\n", advisory, advisory > 1 ? "ies" : "y", 236 advisory,
229 failed, total); 237 advisory > 1 ? "ies" : "y",
238 failed,
239 total);
230 break; 240 break;
231 case OPERATIONAL: 241 case OPERATIONAL:
232 printf ("Status: Operational (%d/%d tests passed)\n", passed, total); 242 printf (_("Status: Operational (%d/%d tests passed)\n"), passed, total);
233 break; 243 break;
234 default: 244 default:
235 printf ("Error: Status '%d' uknown. %d/%d tests passed\n", status, 245 printf (_("Error: Status '%d' uknown. %d/%d tests passed\n"), status,
236 passed, total); 246 passed, total);
237 status = -1; 247 status = -1;
238 break; 248 break;
239 } 249 }
240 return status; 250 return status;
241} 251}
252
242void 253void
243print_value (value_t * p, threshold_t * t) 254print_value (value_t * p, threshold_t * t)
244{ 255{
245 printf ("Id=%3d, Status=%2d {%s , %s}, Value=%3d, Threshold=%3d, %s\n", 256 printf ("Id=%3d, Status=%2d {%s , %s}, Value=%3d, Threshold=%3d, %s\n",
246 p->id, p->status, p->status & 1 ? "PreFailure" : "Advisory ", 257 p->id, p->status, p->status & 1 ? "PreFailure" : "Advisory ",
247 p->status & 2 ? "OnLine " : "OffLine", p->value, t->threshold, 258 p->status & 2 ? "OnLine " : "OffLine", p->value, t->threshold,
248 p->value > t->threshold ? "Passed" : "Failed"); 259 p->value > t->threshold ? "Passed" : "Failed");
249} 260}
261
250void 262void
251print_values (values_t * p, thresholds_t * t) 263print_values (values_t * p, thresholds_t * t)
252{ 264{
@@ -259,18 +271,26 @@ print_values (values_t * p, thresholds_t * t)
259 } 271 }
260 } 272 }
261 printf 273 printf
262 ("OffLineStatus=%d {%s}, AutoOffLine=%s, OffLineTimeout=%d minutes\n", 274 (_("OffLineStatus=%d {%s}, AutoOffLine=%s, OffLineTimeout=%d minutes\n"),
263 p->offline_status, get_offline_text (p->offline_status & 0x7f), 275 p->offline_status,
264 (p->offline_status & 0x80 ? "Yes" : "No"), p->offline_timeout / 60); 276 get_offline_text (p->offline_status & 0x7f),
265 printf ("OffLineCapability=%d {%s %s %s}\n", p->offline_capability, 277 (p->offline_status & 0x80 ? "Yes" : "No"),
266 p->offline_capability & 1 ? "Immediate" : "", 278 p->offline_timeout / 60);
267 p->offline_capability & 2 ? "Auto" : "", 279 printf
268 p->offline_capability & 4 ? "AbortOnCmd" : "SuspendOnCmd"); 280 (_("OffLineCapability=%d {%s %s %s}\n"),
269 printf ("SmartRevision=%d, CheckSum=%d, SmartCapability=%d {%s %s}\n", 281 p->offline_capability,
270 p->revision, p->checksum, p->smart_capability, 282 p->offline_capability & 1 ? "Immediate" : "",
271 p->smart_capability & 1 ? "SaveOnStandBy" : "", 283 p->offline_capability & 2 ? "Auto" : "",
272 p->smart_capability & 2 ? "AutoSave" : ""); 284 p->offline_capability & 4 ? "AbortOnCmd" : "SuspendOnCmd");
285 printf
286 (_("SmartRevision=%d, CheckSum=%d, SmartCapability=%d {%s %s}\n"),
287 p->revision,
288 p->checksum,
289 p->smart_capability,
290 p->smart_capability & 1 ? "SaveOnStandBy" : "",
291 p->smart_capability & 2 ? "AutoSave" : "");
273} 292}
293
274void 294void
275print_thresholds (thresholds_t * p) 295print_thresholds (thresholds_t * p)
276{ 296{
@@ -281,39 +301,49 @@ print_thresholds (thresholds_t * p)
281 for (i = 0; i < NR_ATTRIBUTES; i++) { 301 for (i = 0; i < NR_ATTRIBUTES; i++) {
282 if (threshold->id) { 302 if (threshold->id) {
283 printf ("Id=%3d, Threshold=%3d\n", threshold->id, 303 printf ("Id=%3d, Threshold=%3d\n", threshold->id,
284 threshold->threshold); } 304 threshold->threshold); }
285 ++threshold; 305 ++threshold;
286 } 306 }
287 printf ("CheckSum=%d\n", p->checksum); 307 printf ("CheckSum=%d\n", p->checksum);
288} 308}
309
289int 310int
290smart_cmd_simple (int fd, enum SmartCommand command, __u8 val0, 311smart_cmd_simple (int fd, enum SmartCommand command, __u8 val0,
291 char show_error) 312 char show_error)
292{ 313{
293 __u8 args[4] = {
294 WIN_SMART, val0, smart_command[command].value, 0};
295 int e = 0; 314 int e = 0;
315 __u8 args[4];
316 args[0] = WIN_SMART;
317 args[1] = val0;
318 args[2] = smart_command[command].value;
319 args[3] = 0;
296 if (ioctl (fd, HDIO_DRIVE_CMD, &args)) { 320 if (ioctl (fd, HDIO_DRIVE_CMD, &args)) {
297 e = errno; 321 e = errno;
298 if (show_error) { 322 if (show_error) {
299 printf ("Critical: %s: %s\n", smart_command[command].text, 323 printf (_("Critical: %s: %s\n"), smart_command[command].text, strerror (errno));
300 strerror (errno)); } 324 }
301 } 325 }
302 return e; 326 return e;
303} 327}
328
304int 329int
305smart_read_thresholds (int fd, thresholds_t * thresholds) 330smart_read_thresholds (int fd, thresholds_t * thresholds)
306{ 331{
307 __u8 args[4 + 512] = { 332 int e;
308 WIN_SMART, 0, SMART_READ_THRESHOLDS, 1,}; 333 __u8 args[4 + 512];
334 args[0] = WIN_SMART;
335 args[1] = 0;
336 args[2] = SMART_READ_THRESHOLDS;
337 args[3] = 1;
309 if (ioctl (fd, HDIO_DRIVE_CMD, &args)) { 338 if (ioctl (fd, HDIO_DRIVE_CMD, &args)) {
310 int e = errno; 339 e = errno;
311 printf ("Critical: SMART_READ_THRESHOLDS: %s\n", strerror (errno)); 340 printf (_("Critical: SMART_READ_THRESHOLDS: %s\n"), strerror (errno));
312 return e; 341 return e;
313 } 342 }
314 memcpy (thresholds, args + 4, 512); 343 memcpy (thresholds, args + 4, 512);
315 return 0; 344 return 0;
316} 345}
346
317void 347void
318show_version () 348show_version ()
319{ 349{
@@ -321,18 +351,28 @@ show_version ()
321 printf ("Nagios feature - Robert Dale <rdale@digital-mission.com>\n"); 351 printf ("Nagios feature - Robert Dale <rdale@digital-mission.com>\n");
322 printf ("(C) 1999 Ragnar Hojland Espinosa <ragnar@lightside.dhis.org>\n"); 352 printf ("(C) 1999 Ragnar Hojland Espinosa <ragnar@lightside.dhis.org>\n");
323} 353}
354
324void 355void
325show_help () 356show_help ()
326{ 357{
327 printf ("Usage: check_ide-smart [DEVICE] [OPTION]\n" 358 printf (_("\
328 " -d, --device=DEVICE Select device DEVICE\n" 359Usage: check_ide-smart [DEVICE] [OPTION]\n\
329 " -i, --immediate Perform immediately offline tests\n" 360 -d, --device=DEVICE\n\
330 " -q, --quiet-check Returns the number of failed tests\n" 361 Select device DEVICE\n\
331 " -1, --auto-on Turn on automatic offline tests\n" 362 -i, --immediate\n\
332 " -0, --auto-off Turn off automatic offline tests\n" 363 Perform immediately offline tests\n\
333 " -n, --net-saint Output suitable for Net Saint\n" 364 -q, --quiet-check\n\
334 " -h, --help\n" " -V, --version\n"); 365 Returns the number of failed tests\n\
366 -1, --auto-on\n\
367 Turn on automatic offline tests\n\
368 -0, --auto-off\n\
369 Turn off automatic offline tests\n\
370 -n, --net-saint\n\
371 Output suitable for Net Saint\n\
372 -h, --help\n\
373 -V, --version\n"));
335} 374}
375
336int 376int
337main (int argc, char *argv[]) 377main (int argc, char *argv[])
338{ 378{
@@ -340,9 +380,13 @@ main (int argc, char *argv[])
340 int command = -1; 380 int command = -1;
341 int o, longindex; 381 int o, longindex;
342 int retval = 0; 382 int retval = 0;
343 383
344 const struct option longopts[] = { 384 thresholds_t thresholds;
345 {"device", required_argument, 0, 'd'}, 385 values_t values;
386 int fd;
387
388 static struct option longopts[] = {
389 {"device", required_argument, 0, 'd'},
346 {"immediate", no_argument, 0, 'i'}, 390 {"immediate", no_argument, 0, 'i'},
347 {"quiet-check", no_argument, 0, 'q'}, 391 {"quiet-check", no_argument, 0, 'q'},
348 {"auto-on", no_argument, 0, '1'}, 392 {"auto-on", no_argument, 0, '1'},
@@ -351,13 +395,14 @@ main (int argc, char *argv[])
351 {"help", no_argument, 0, 'h'}, 395 {"help", no_argument, 0, 'h'},
352 {"version", no_argument, 0, 'V'}, {0, 0, 0, 0} 396 {"version", no_argument, 0, 'V'}, {0, 0, 0, 0}
353 }; 397 };
354 398
355 while (1) { 399 while (1) {
356 400
357 o = getopt_long (argc, argv, "+d:iq10nhV", longopts, &longindex); 401 o = getopt_long (argc, argv, "+d:iq10nhV", longopts, &longindex);
358 402
359 if (o == -1 || o == EOF) 403 if (o == -1 || o == EOF)
360 break; 404 break;
405
361 switch (o) { 406 switch (o) {
362 case 'd': 407 case 'd':
363 device = optarg; 408 device = optarg;
@@ -384,57 +429,60 @@ main (int argc, char *argv[])
384 show_version (); 429 show_version ();
385 return 0; 430 return 0;
386 default: 431 default:
387 printf ("Try `%s --help' for more information.\n", argv[0]); 432 printf (_("Try `%s --help' for more information.\n"), argv[0]);
388 return 1; 433 return 1;
389 } 434 }
435
390 if (optind < argc) { 436 if (optind < argc) {
391 device = argv[optind]; 437 device = argv[optind];
392 } 438 }
439
393 if (!device) { 440 if (!device) {
394 show_help (); 441 show_help ();
395 show_version (); 442 show_version ();
396 return -1; 443 return -1;
397 } 444 }
398 if (1) { 445
399 thresholds_t thresholds; 446 fd = open (device, O_RDONLY);
400 values_t values; 447
401 int fd = open (device, O_RDONLY); 448 if (fd < 0) {
402 if (fd < 0) { 449 printf (_("Critical: Couldn't open device: %s\n"), strerror (errno));
403 printf ("Critical: Couldn't open device: %s\n", strerror (errno)); 450 return 2;
404 return 2; 451 }
405 } 452
406 if (smart_cmd_simple (fd, SMART_CMD_ENABLE, 0, TRUE)) { 453 if (smart_cmd_simple (fd, SMART_CMD_ENABLE, 0, TRUE)) {
407 printf ("Critical: SMART_CMD_ENABLE\n"); 454 printf (_("Critical: SMART_CMD_ENABLE\n"));
408 return 2; 455 return 2;
409 } 456 }
410 switch (command) { 457
411 case 0: 458 switch (command) {
412 retval = smart_cmd_simple (fd, SMART_CMD_AUTO_OFFLINE, 0, TRUE); 459 case 0:
413 break; 460 retval = smart_cmd_simple (fd, SMART_CMD_AUTO_OFFLINE, 0, TRUE);
414 case 1: 461 break;
415 retval = smart_cmd_simple (fd, SMART_CMD_AUTO_OFFLINE, 0xF8, TRUE); 462 case 1:
416 break; 463 retval = smart_cmd_simple (fd, SMART_CMD_AUTO_OFFLINE, 0xF8, TRUE);
417 case 2: 464 break;
418 retval = smart_cmd_simple (fd, SMART_CMD_IMMEDIATE_OFFLINE, 0, TRUE); 465 case 2:
419 break; 466 retval = smart_cmd_simple (fd, SMART_CMD_IMMEDIATE_OFFLINE, 0, TRUE);
420 case 3: 467 break;
421 smart_read_values (fd, &values); 468 case 3:
422 smart_read_thresholds (fd, &thresholds); 469 smart_read_values (fd, &values);
423 retval = values_not_passed (&values, &thresholds); 470 smart_read_thresholds (fd, &thresholds);
424 break; 471 retval = values_not_passed (&values, &thresholds);
425 case 4: 472 break;
426 smart_read_values (fd, &values); 473 case 4:
427 smart_read_thresholds (fd, &thresholds); 474 smart_read_values (fd, &values);
428 retval = net_saint (&values, &thresholds); 475 smart_read_thresholds (fd, &thresholds);
429 break; 476 retval = net_saint (&values, &thresholds);
430 default: 477 break;
431 smart_read_values (fd, &values); 478 default:
432 smart_read_thresholds (fd, &thresholds); 479 smart_read_values (fd, &values);
433 print_values (&values, &thresholds); 480 smart_read_thresholds (fd, &thresholds);
434 break; 481 print_values (&values, &thresholds);
435 } 482 break;
436 close (fd);
437 } 483 }
438 return retval; 484 close (fd);
439 } 485 }
486 return retval;
487}
440 488