summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/Makefile.am1
-rw-r--r--plugins/check_ide_smart.c155
-rw-r--r--plugins/check_ide_smart.d/config.h15
3 files changed, 101 insertions, 70 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 30ca63d1..8983f25c 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -55,6 +55,7 @@ EXTRA_DIST = t \
55 check_hpjd.d \ 55 check_hpjd.d \
56 check_game.d \ 56 check_game.d \
57 check_radius.d \ 57 check_radius.d \
58 check_ide_smart.d \
58 check_time.d \ 59 check_time.d \
59 check_nagios.d \ 60 check_nagios.d \
60 check_dbi.d \ 61 check_dbi.d \
diff --git a/plugins/check_ide_smart.c b/plugins/check_ide_smart.c
index 16fe3d01..b13c7101 100644
--- a/plugins/check_ide_smart.c
+++ b/plugins/check_ide_smart.c
@@ -39,6 +39,8 @@ 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#include "check_ide_smart.d/config.h"
43#include "states.h"
42 44
43static void print_help(void); 45static void print_help(void);
44void print_usage(void); 46void print_usage(void);
@@ -46,6 +48,7 @@ void print_usage(void);
46#include <sys/stat.h> 48#include <sys/stat.h>
47#include <sys/ioctl.h> 49#include <sys/ioctl.h>
48#include <fcntl.h> 50#include <fcntl.h>
51
49#ifdef __linux__ 52#ifdef __linux__
50# include <linux/hdreg.h> 53# include <linux/hdreg.h>
51# include <linux/types.h> 54# include <linux/types.h>
@@ -133,25 +136,20 @@ enum SmartCommand {
133 SMART_CMD_AUTO_OFFLINE 136 SMART_CMD_AUTO_OFFLINE
134}; 137};
135 138
136static char *get_offline_text(int); 139static char *get_offline_text(int /*status*/);
137static int smart_read_values(int, values_t *); 140static int smart_read_values(int /*fd*/, values_t * /*values*/);
138static int nagios(values_t *, thresholds_t *); 141static mp_state_enum compare_values_and_thresholds(values_t * /*p*/, thresholds_t * /*t*/);
139static void print_value(value_t *, threshold_t *); 142static void print_value(value_t * /*p*/, threshold_t * /*t*/);
140static void print_values(values_t *, thresholds_t *); 143static void print_values(values_t * /*p*/, thresholds_t * /*t*/);
141static int smart_cmd_simple(int, enum SmartCommand, uint8_t, bool); 144static mp_state_enum smart_cmd_simple(int /*fd*/, enum SmartCommand /*command*/, uint8_t /*val0*/, bool /*show_error*/);
142static int smart_read_thresholds(int, thresholds_t *); 145static int smart_read_thresholds(int /*fd*/, thresholds_t * /*thresholds*/);
143static bool verbose = false; 146static int verbose = 0;
144 147
145int main(int argc, char *argv[]) { 148typedef struct {
146 char *device = NULL; 149 int errorcode;
147 int o; 150 check_ide_smart_config config;
148 int longindex; 151} check_ide_smart_config_wrapper;
149 int retval = 0; 152static check_ide_smart_config_wrapper process_arguments(int argc, char **argv) {
150
151 thresholds_t thresholds;
152 values_t values;
153 int fd;
154
155 static struct option longopts[] = {{"device", required_argument, 0, 'd'}, 153 static struct option longopts[] = {{"device", required_argument, 0, 'd'},
156 {"immediate", no_argument, 0, 'i'}, 154 {"immediate", no_argument, 0, 'i'},
157 {"quiet-check", no_argument, 0, 'q'}, 155 {"quiet-check", no_argument, 0, 'q'},
@@ -162,24 +160,22 @@ int main(int argc, char *argv[]) {
162 {"version", no_argument, 0, 'V'}, 160 {"version", no_argument, 0, 'V'},
163 {0, 0, 0, 0}}; 161 {0, 0, 0, 0}};
164 162
165 /* Parse extra opts if any */ 163 check_ide_smart_config_wrapper result = {
166 argv = np_extra_opts(&argc, argv, progname); 164 .errorcode = OK,
167 165 .config = check_ide_smart_init(),
168 setlocale(LC_ALL, ""); 166 };
169 bindtextdomain(PACKAGE, LOCALEDIR);
170 textdomain(PACKAGE);
171 167
172 while (true) { 168 while (true) {
169 int longindex = 0;
170 int option_index = getopt_long(argc, argv, "+d:iq10nhVv", longopts, &longindex);
173 171
174 o = getopt_long(argc, argv, "+d:iq10nhVv", longopts, &longindex); 172 if (option_index == -1 || option_index == EOF || option_index == 1) {
175
176 if (o == -1 || o == EOF || o == 1) {
177 break; 173 break;
178 } 174 }
179 175
180 switch (o) { 176 switch (option_index) {
181 case 'd': 177 case 'd':
182 device = optarg; 178 result.config.device = optarg;
183 break; 179 break;
184 case 'q': 180 case 'q':
185 fprintf(stderr, "%s\n", _("DEPRECATION WARNING: the -q switch (quiet output) is no longer \"quiet\".")); 181 fprintf(stderr, "%s\n", _("DEPRECATION WARNING: the -q switch (quiet output) is no longer \"quiet\"."));
@@ -189,63 +185,82 @@ int main(int argc, char *argv[]) {
189 case '1': 185 case '1':
190 case '0': 186 case '0':
191 printf("%s\n", _("SMART commands are broken and have been disabled (See Notes in --help).")); 187 printf("%s\n", _("SMART commands are broken and have been disabled (See Notes in --help)."));
192 return STATE_CRITICAL; 188 result.errorcode = ERROR;
189 return result;
193 break; 190 break;
194 case 'n': 191 case 'n':
195 fprintf(stderr, "%s\n", _("DEPRECATION WARNING: the -n switch (Nagios-compatible output) is now the")); 192 fprintf(stderr, "%s\n", _("DEPRECATION WARNING: the -n switch (Nagios-compatible output) is now the"));
196 fprintf(stderr, "%s\n", _("default and will be removed from future releases.")); 193 fprintf(stderr, "%s\n", _("default and will be removed from future releases."));
197 break; 194 break;
198 case 'v': /* verbose */ 195 case 'v': /* verbose */
199 verbose = true; 196 verbose++;
200 break; 197 break;
201 case 'h': 198 case 'h':
202 print_help(); 199 print_help();
203 return STATE_UNKNOWN; 200 exit(STATE_UNKNOWN);
204 case 'V': 201 case 'V':
205 print_revision(progname, NP_VERSION); 202 print_revision(progname, NP_VERSION);
206 return STATE_UNKNOWN; 203 exit(STATE_UNKNOWN);
207 default: 204 default:
208 usage5(); 205 usage5();
209 } 206 }
210 } 207 if (optind < argc) {
208 result.config.device = argv[optind];
209 }
211 210
212 if (optind < argc) { 211 if (!result.config.device) {
213 device = argv[optind]; 212 print_help();
213 exit(STATE_UNKNOWN);
214 }
214 } 215 }
216 return result;
217}
215 218
216 if (!device) { 219int main(int argc, char *argv[]) {
217 print_help(); 220 setlocale(LC_ALL, "");
218 return STATE_UNKNOWN; 221 bindtextdomain(PACKAGE, LOCALEDIR);
222 textdomain(PACKAGE);
223
224 /* Parse extra opts if any */
225 argv = np_extra_opts(&argc, argv, progname);
226
227 check_ide_smart_config_wrapper tmp_config = process_arguments(argc, argv);
228
229 if (tmp_config.errorcode != OK) {
230 die(STATE_UNKNOWN, _("Failed to parse commandline"));
219 } 231 }
220 232
221 fd = open(device, OPEN_MODE); 233 check_ide_smart_config config = tmp_config.config;
222 234
223 if (fd < 0) { 235 int device_file_descriptor = open(config.device, OPEN_MODE);
224 printf(_("CRITICAL - Couldn't open device %s: %s\n"), device, strerror(errno)); 236
237 if (device_file_descriptor < 0) {
238 printf(_("CRITICAL - Couldn't open device %s: %s\n"), config.device, strerror(errno));
225 return STATE_CRITICAL; 239 return STATE_CRITICAL;
226 } 240 }
227 241
228 if (smart_cmd_simple(fd, SMART_CMD_ENABLE, 0, false)) { 242 if (smart_cmd_simple(device_file_descriptor, SMART_CMD_ENABLE, 0, false)) {
229 printf(_("CRITICAL - SMART_CMD_ENABLE\n")); 243 printf(_("CRITICAL - SMART_CMD_ENABLE\n"));
230 return STATE_CRITICAL; 244 return STATE_CRITICAL;
231 } 245 }
232 246
233 smart_read_values(fd, &values); 247 values_t values;
234 smart_read_thresholds(fd, &thresholds); 248 smart_read_values(device_file_descriptor, &values);
235 retval = nagios(&values, &thresholds); 249 thresholds_t thresholds;
250 smart_read_thresholds(device_file_descriptor, &thresholds);
251 mp_state_enum retval = compare_values_and_thresholds(&values, &thresholds);
236 if (verbose) { 252 if (verbose) {
237 print_values(&values, &thresholds); 253 print_values(&values, &thresholds);
238 } 254 }
239 255
240 close(fd); 256 close(device_file_descriptor);
241 return retval; 257 return retval;
242} 258}
243 259
244char *get_offline_text(int status) { 260char *get_offline_text(int status) {
245 int i; 261 for (int index = 0; offline_status_text[index].text; index++) {
246 for (i = 0; offline_status_text[i].text; i++) { 262 if (offline_status_text[index].value == status) {
247 if (offline_status_text[i].value == status) { 263 return offline_status_text[index].text;
248 return offline_status_text[i].text;
249 } 264 }
250 } 265 }
251 return "UNKNOWN"; 266 return "UNKNOWN";
@@ -253,16 +268,16 @@ char *get_offline_text(int status) {
253 268
254int smart_read_values(int fd, values_t *values) { 269int smart_read_values(int fd, values_t *values) {
255#ifdef __linux__ 270#ifdef __linux__
256 int e; 271 int errno_storage;
257 uint8_t args[4 + 512]; 272 uint8_t args[4 + 512];
258 args[0] = WIN_SMART; 273 args[0] = WIN_SMART;
259 args[1] = 0; 274 args[1] = 0;
260 args[2] = SMART_READ_VALUES; 275 args[2] = SMART_READ_VALUES;
261 args[3] = 1; 276 args[3] = 1;
262 if (ioctl(fd, HDIO_DRIVE_CMD, &args)) { 277 if (ioctl(fd, HDIO_DRIVE_CMD, &args)) {
263 e = errno; 278 errno_storage = errno;
264 printf(_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror(errno)); 279 printf(_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror(errno));
265 return e; 280 return errno_storage;
266 } 281 }
267 memcpy(values, args + 4, 512); 282 memcpy(values, args + 4, 512);
268#endif /* __linux__ */ 283#endif /* __linux__ */
@@ -298,7 +313,7 @@ int smart_read_values(int fd, values_t *values) {
298 return 0; 313 return 0;
299} 314}
300 315
301int nagios(values_t *p, thresholds_t *t) { 316mp_state_enum compare_values_and_thresholds(values_t *p, thresholds_t *t) {
302 value_t *value = p->values; 317 value_t *value = p->values;
303 threshold_t *threshold = t->thresholds; 318 threshold_t *threshold = t->thresholds;
304 int status = OPERATIONAL; 319 int status = OPERATIONAL;
@@ -307,8 +322,7 @@ int nagios(values_t *p, thresholds_t *t) {
307 int failed = 0; 322 int failed = 0;
308 int passed = 0; 323 int passed = 0;
309 int total = 0; 324 int total = 0;
310 int i; 325 for (int i = 0; i < NR_ATTRIBUTES; i++) {
311 for (i = 0; i < NR_ATTRIBUTES; i++) {
312 if (value->id && threshold->id && value->id == threshold->id) { 326 if (value->id && threshold->id && value->id == threshold->id) {
313 if (value->value < threshold->threshold) { 327 if (value->value < threshold->threshold) {
314 ++failed; 328 ++failed;
@@ -327,6 +341,7 @@ int nagios(values_t *p, thresholds_t *t) {
327 ++value; 341 ++value;
328 ++threshold; 342 ++threshold;
329 } 343 }
344
330 switch (status) { 345 switch (status) {
331 case PREFAILURE: 346 case PREFAILURE:
332 printf(_("CRITICAL - %d Harddrive PreFailure%cDetected! %d/%d tests failed.\n"), prefailure, prefailure > 1 ? 's' : ' ', failed, 347 printf(_("CRITICAL - %d Harddrive PreFailure%cDetected! %d/%d tests failed.\n"), prefailure, prefailure > 1 ? 's' : ' ', failed,
@@ -371,8 +386,8 @@ void print_values(values_t *p, thresholds_t *t) {
371 p->smart_capability & 1 ? "SaveOnStandBy" : "", p->smart_capability & 2 ? "AutoSave" : ""); 386 p->smart_capability & 1 ? "SaveOnStandBy" : "", p->smart_capability & 2 ? "AutoSave" : "");
372} 387}
373 388
374int smart_cmd_simple(int fd, enum SmartCommand command, uint8_t val0, bool show_error) { 389mp_state_enum smart_cmd_simple(int fd, enum SmartCommand command, uint8_t val0, bool show_error) {
375 int e = STATE_UNKNOWN; 390 mp_state_enum result = STATE_UNKNOWN;
376#ifdef __linux__ 391#ifdef __linux__
377 uint8_t args[4]; 392 uint8_t args[4];
378 args[0] = WIN_SMART; 393 args[0] = WIN_SMART;
@@ -380,12 +395,12 @@ int smart_cmd_simple(int fd, enum SmartCommand command, uint8_t val0, bool show_
380 args[2] = smart_command[command].value; 395 args[2] = smart_command[command].value;
381 args[3] = 0; 396 args[3] = 0;
382 if (ioctl(fd, HDIO_DRIVE_CMD, &args)) { 397 if (ioctl(fd, HDIO_DRIVE_CMD, &args)) {
383 e = STATE_CRITICAL; 398 result = STATE_CRITICAL;
384 if (show_error) { 399 if (show_error) {
385 printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno)); 400 printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno));
386 } 401 }
387 } else { 402 } else {
388 e = STATE_OK; 403 result = STATE_OK;
389 if (show_error) { 404 if (show_error) {
390 printf(_("OK - Command sent (%s)\n"), smart_command[command].text); 405 printf(_("OK - Command sent (%s)\n"), smart_command[command].text);
391 } 406 }
@@ -413,33 +428,33 @@ int smart_cmd_simple(int fd, enum SmartCommand command, uint8_t val0, bool show_
413 } 428 }
414 429
415 if (errno != 0) { 430 if (errno != 0) {
416 e = STATE_CRITICAL; 431 result = STATE_CRITICAL;
417 if (show_error) { 432 if (show_error) {
418 printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno)); 433 printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno));
419 } 434 }
420 } else { 435 } else {
421 e = STATE_OK; 436 result = STATE_OK;
422 if (show_error) { 437 if (show_error) {
423 printf(_("OK - Command sent (%s)\n"), smart_command[command].text); 438 printf(_("OK - Command sent (%s)\n"), smart_command[command].text);
424 } 439 }
425 } 440 }
426 441
427#endif /* __NetBSD__ */ 442#endif /* __NetBSD__ */
428 return e; 443 return result;
429} 444}
430 445
431int smart_read_thresholds(int fd, thresholds_t *thresholds) { 446int smart_read_thresholds(int fd, thresholds_t *thresholds) {
432#ifdef __linux__ 447#ifdef __linux__
433 int e; 448 int errno_storage;
434 uint8_t args[4 + 512]; 449 uint8_t args[4 + 512];
435 args[0] = WIN_SMART; 450 args[0] = WIN_SMART;
436 args[1] = 0; 451 args[1] = 0;
437 args[2] = SMART_READ_THRESHOLDS; 452 args[2] = SMART_READ_THRESHOLDS;
438 args[3] = 1; 453 args[3] = 1;
439 if (ioctl(fd, HDIO_DRIVE_CMD, &args)) { 454 if (ioctl(fd, HDIO_DRIVE_CMD, &args)) {
440 e = errno; 455 errno_storage = errno;
441 printf(_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror(errno)); 456 printf(_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror(errno));
442 return e; 457 return errno_storage;
443 } 458 }
444 memcpy(thresholds, args + 4, 512); 459 memcpy(thresholds, args + 4, 512);
445#endif /* __linux__ */ 460#endif /* __linux__ */
@@ -465,9 +480,9 @@ int smart_read_thresholds(int fd, thresholds_t *thresholds) {
465 } 480 }
466 481
467 if (errno != 0) { 482 if (errno != 0) {
468 int e = errno; 483 int errno_storage = errno;
469 printf(_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror(errno)); 484 printf(_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror(errno));
470 return e; 485 return errno_storage;
471 } 486 }
472 487
473 (void)memcpy(thresholds, inbuf, 512); 488 (void)memcpy(thresholds, inbuf, 512);
diff --git a/plugins/check_ide_smart.d/config.h b/plugins/check_ide_smart.d/config.h
new file mode 100644
index 00000000..36899abe
--- /dev/null
+++ b/plugins/check_ide_smart.d/config.h
@@ -0,0 +1,15 @@
1#pragma once
2
3#include "../../config.h"
4#include <stddef.h>
5
6typedef struct {
7 char *device;
8} check_ide_smart_config;
9
10check_ide_smart_config check_ide_smart_init() {
11 check_ide_smart_config tmp = {
12 .device = NULL,
13 };
14 return tmp;
15}