diff options
| -rw-r--r-- | plugins/Makefile.am | 1 | ||||
| -rw-r--r-- | plugins/check_ide_smart.c | 259 | ||||
| -rw-r--r-- | plugins/check_ide_smart.d/config.h | 15 |
3 files changed, 157 insertions, 118 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am index fa159f4a..a35f273e 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am | |||
| @@ -66,6 +66,7 @@ EXTRA_DIST = t \ | |||
| 66 | check_hpjd.d \ | 66 | check_hpjd.d \ |
| 67 | check_game.d \ | 67 | check_game.d \ |
| 68 | check_radius.d \ | 68 | check_radius.d \ |
| 69 | check_ide_smart.d \ | ||
| 69 | check_curl.d \ | 70 | check_curl.d \ |
| 70 | check_disk.d \ | 71 | check_disk.d \ |
| 71 | check_time.d \ | 72 | check_time.d \ |
diff --git a/plugins/check_ide_smart.c b/plugins/check_ide_smart.c index 16fe3d01..c1325cf9 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 | ||
| 43 | static void print_help(void); | 45 | static void print_help(void); |
| 44 | void print_usage(void); | 46 | void 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> |
| @@ -77,30 +80,30 @@ void print_usage(void); | |||
| 77 | #define OPERATIONAL 0 | 80 | #define OPERATIONAL 0 |
| 78 | #define UNKNOWN -1 | 81 | #define UNKNOWN -1 |
| 79 | 82 | ||
| 80 | typedef struct threshold_s { | 83 | typedef struct { |
| 81 | uint8_t id; | 84 | uint8_t id; |
| 82 | uint8_t threshold; | 85 | uint8_t threshold; |
| 83 | uint8_t reserved[10]; | 86 | uint8_t reserved[10]; |
| 84 | } __attribute__((packed)) threshold_t; | 87 | } __attribute__((packed)) smart_threshold; |
| 85 | 88 | ||
| 86 | typedef struct thresholds_s { | 89 | typedef struct { |
| 87 | uint16_t revision; | 90 | uint16_t revision; |
| 88 | threshold_t thresholds[NR_ATTRIBUTES]; | 91 | smart_threshold thresholds[NR_ATTRIBUTES]; |
| 89 | uint8_t reserved[18]; | 92 | uint8_t reserved[18]; |
| 90 | uint8_t vendor[131]; | 93 | uint8_t vendor[131]; |
| 91 | uint8_t checksum; | 94 | uint8_t checksum; |
| 92 | } __attribute__((packed)) thresholds_t; | 95 | } __attribute__((packed)) smart_thresholds; |
| 93 | 96 | ||
| 94 | typedef struct value_s { | 97 | typedef struct { |
| 95 | uint8_t id; | 98 | uint8_t id; |
| 96 | uint16_t status; | 99 | uint16_t status; |
| 97 | uint8_t value; | 100 | uint8_t value; |
| 98 | uint8_t vendor[8]; | 101 | uint8_t vendor[8]; |
| 99 | } __attribute__((packed)) value_t; | 102 | } __attribute__((packed)) smart_value; |
| 100 | 103 | ||
| 101 | typedef struct values_s { | 104 | typedef struct { |
| 102 | uint16_t revision; | 105 | uint16_t revision; |
| 103 | value_t values[NR_ATTRIBUTES]; | 106 | smart_value values[NR_ATTRIBUTES]; |
| 104 | uint8_t offline_status; | 107 | uint8_t offline_status; |
| 105 | uint8_t vendor1; | 108 | uint8_t vendor1; |
| 106 | uint16_t offline_timeout; | 109 | uint16_t offline_timeout; |
| @@ -110,7 +113,7 @@ typedef struct values_s { | |||
| 110 | uint8_t reserved[16]; | 113 | uint8_t reserved[16]; |
| 111 | uint8_t vendor[125]; | 114 | uint8_t vendor[125]; |
| 112 | uint8_t checksum; | 115 | uint8_t checksum; |
| 113 | } __attribute__((packed)) values_t; | 116 | } __attribute__((packed)) smart_values; |
| 114 | 117 | ||
| 115 | static struct { | 118 | static struct { |
| 116 | uint8_t value; | 119 | uint8_t value; |
| @@ -133,25 +136,20 @@ enum SmartCommand { | |||
| 133 | SMART_CMD_AUTO_OFFLINE | 136 | SMART_CMD_AUTO_OFFLINE |
| 134 | }; | 137 | }; |
| 135 | 138 | ||
| 136 | static char *get_offline_text(int); | 139 | static char *get_offline_text(int /*status*/); |
| 137 | static int smart_read_values(int, values_t *); | 140 | static int smart_read_values(int /*fd*/, smart_values * /*values*/); |
| 138 | static int nagios(values_t *, thresholds_t *); | 141 | static mp_state_enum compare_values_and_thresholds(smart_values * /*p*/, smart_thresholds * /*t*/); |
| 139 | static void print_value(value_t *, threshold_t *); | 142 | static void print_value(smart_value * /*p*/, smart_threshold * /*t*/); |
| 140 | static void print_values(values_t *, thresholds_t *); | 143 | static void print_values(smart_values * /*p*/, smart_thresholds * /*t*/); |
| 141 | static int smart_cmd_simple(int, enum SmartCommand, uint8_t, bool); | 144 | static mp_state_enum smart_cmd_simple(int /*fd*/, enum SmartCommand /*command*/, uint8_t /*val0*/, bool /*show_error*/); |
| 142 | static int smart_read_thresholds(int, thresholds_t *); | 145 | static int smart_read_thresholds(int /*fd*/, smart_thresholds * /*thresholds*/); |
| 143 | static bool verbose = false; | 146 | static int verbose = 0; |
| 144 | 147 | ||
| 145 | int main(int argc, char *argv[]) { | 148 | typedef 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; | 152 | static 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,84 +185,103 @@ 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 | } |
| 211 | 208 | ||
| 212 | if (optind < argc) { | 209 | if (optind < argc) { |
| 213 | device = argv[optind]; | 210 | result.config.device = argv[optind]; |
| 214 | } | 211 | } |
| 215 | 212 | ||
| 216 | if (!device) { | 213 | if (result.config.device == NULL) { |
| 217 | print_help(); | 214 | print_help(); |
| 218 | return STATE_UNKNOWN; | 215 | exit(STATE_UNKNOWN); |
| 216 | } | ||
| 217 | |||
| 218 | return result; | ||
| 219 | } | ||
| 220 | |||
| 221 | int main(int argc, char *argv[]) { | ||
| 222 | setlocale(LC_ALL, ""); | ||
| 223 | bindtextdomain(PACKAGE, LOCALEDIR); | ||
| 224 | textdomain(PACKAGE); | ||
| 225 | |||
| 226 | /* Parse extra opts if any */ | ||
| 227 | argv = np_extra_opts(&argc, argv, progname); | ||
| 228 | |||
| 229 | check_ide_smart_config_wrapper tmp_config = process_arguments(argc, argv); | ||
| 230 | |||
| 231 | if (tmp_config.errorcode != OK) { | ||
| 232 | die(STATE_UNKNOWN, _("Failed to parse commandline")); | ||
| 219 | } | 233 | } |
| 220 | 234 | ||
| 221 | fd = open(device, OPEN_MODE); | 235 | check_ide_smart_config config = tmp_config.config; |
| 222 | 236 | ||
| 223 | if (fd < 0) { | 237 | int device_file_descriptor = open(config.device, OPEN_MODE); |
| 224 | printf(_("CRITICAL - Couldn't open device %s: %s\n"), device, strerror(errno)); | 238 | |
| 239 | if (device_file_descriptor < 0) { | ||
| 240 | printf(_("CRITICAL - Couldn't open device %s: %s\n"), config.device, strerror(errno)); | ||
| 225 | return STATE_CRITICAL; | 241 | return STATE_CRITICAL; |
| 226 | } | 242 | } |
| 227 | 243 | ||
| 228 | if (smart_cmd_simple(fd, SMART_CMD_ENABLE, 0, false)) { | 244 | if (smart_cmd_simple(device_file_descriptor, SMART_CMD_ENABLE, 0, false)) { |
| 229 | printf(_("CRITICAL - SMART_CMD_ENABLE\n")); | 245 | printf(_("CRITICAL - SMART_CMD_ENABLE\n")); |
| 230 | return STATE_CRITICAL; | 246 | return STATE_CRITICAL; |
| 231 | } | 247 | } |
| 232 | 248 | ||
| 233 | smart_read_values(fd, &values); | 249 | smart_values values; |
| 234 | smart_read_thresholds(fd, &thresholds); | 250 | smart_read_values(device_file_descriptor, &values); |
| 235 | retval = nagios(&values, &thresholds); | 251 | smart_thresholds thresholds; |
| 252 | smart_read_thresholds(device_file_descriptor, &thresholds); | ||
| 253 | mp_state_enum retval = compare_values_and_thresholds(&values, &thresholds); | ||
| 236 | if (verbose) { | 254 | if (verbose) { |
| 237 | print_values(&values, &thresholds); | 255 | print_values(&values, &thresholds); |
| 238 | } | 256 | } |
| 239 | 257 | ||
| 240 | close(fd); | 258 | close(device_file_descriptor); |
| 241 | return retval; | 259 | return retval; |
| 242 | } | 260 | } |
| 243 | 261 | ||
| 244 | char *get_offline_text(int status) { | 262 | char *get_offline_text(int status) { |
| 245 | int i; | 263 | for (int index = 0; offline_status_text[index].text; index++) { |
| 246 | for (i = 0; offline_status_text[i].text; i++) { | 264 | if (offline_status_text[index].value == status) { |
| 247 | if (offline_status_text[i].value == status) { | 265 | return offline_status_text[index].text; |
| 248 | return offline_status_text[i].text; | ||
| 249 | } | 266 | } |
| 250 | } | 267 | } |
| 251 | return "UNKNOWN"; | 268 | return "UNKNOWN"; |
| 252 | } | 269 | } |
| 253 | 270 | ||
| 254 | int smart_read_values(int fd, values_t *values) { | 271 | int smart_read_values(int file_descriptor, smart_values *values) { |
| 255 | #ifdef __linux__ | 272 | #ifdef __linux__ |
| 256 | int e; | ||
| 257 | uint8_t args[4 + 512]; | 273 | uint8_t args[4 + 512]; |
| 258 | args[0] = WIN_SMART; | 274 | args[0] = WIN_SMART; |
| 259 | args[1] = 0; | 275 | args[1] = 0; |
| 260 | args[2] = SMART_READ_VALUES; | 276 | args[2] = SMART_READ_VALUES; |
| 261 | args[3] = 1; | 277 | args[3] = 1; |
| 262 | if (ioctl(fd, HDIO_DRIVE_CMD, &args)) { | 278 | if (ioctl(file_descriptor, HDIO_DRIVE_CMD, &args)) { |
| 263 | e = errno; | 279 | int errno_storage = errno; |
| 264 | printf(_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror(errno)); | 280 | printf(_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror(errno)); |
| 265 | return e; | 281 | return errno_storage; |
| 266 | } | 282 | } |
| 267 | memcpy(values, args + 4, 512); | 283 | memcpy(values, args + 4, 512); |
| 268 | #endif /* __linux__ */ | 284 | #elif defined __NetBSD__ |
| 269 | #ifdef __NetBSD__ | ||
| 270 | struct atareq req; | 285 | struct atareq req; |
| 271 | unsigned char inbuf[DEV_BSIZE]; | 286 | unsigned char inbuf[DEV_BSIZE]; |
| 272 | 287 | ||
| @@ -281,34 +296,37 @@ int smart_read_values(int fd, values_t *values) { | |||
| 281 | req.datalen = sizeof(inbuf); | 296 | req.datalen = sizeof(inbuf); |
| 282 | req.cylinder = WDSMART_CYL; | 297 | req.cylinder = WDSMART_CYL; |
| 283 | 298 | ||
| 284 | if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { | 299 | if (ioctl(file_descriptor, ATAIOCCOMMAND, &req) == 0) { |
| 285 | if (req.retsts != ATACMD_OK) { | 300 | if (req.retsts != ATACMD_OK) { |
| 286 | errno = ENODEV; | 301 | errno = ENODEV; |
| 287 | } | 302 | } |
| 288 | } | 303 | } |
| 289 | 304 | ||
| 290 | if (errno != 0) { | 305 | if (errno != 0) { |
| 291 | int e = errno; | 306 | int errno_storage = errno; |
| 292 | printf(_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror(errno)); | 307 | printf(_("CRITICAL - SMART_READ_VALUES: %s\n"), strerror(errno)); |
| 293 | return e; | 308 | return errno_storage; |
| 294 | } | 309 | } |
| 295 | 310 | ||
| 296 | (void)memcpy(values, inbuf, 512); | 311 | (void)memcpy(values, inbuf, 512); |
| 297 | #endif /* __NetBSD__ */ | 312 | #else // __linux__ || __NetBSD__ |
| 313 | # error Not implemented for this OS | ||
| 314 | #endif | ||
| 315 | |||
| 298 | return 0; | 316 | return 0; |
| 299 | } | 317 | } |
| 300 | 318 | ||
| 301 | int nagios(values_t *p, thresholds_t *t) { | 319 | mp_state_enum compare_values_and_thresholds(smart_values *values, smart_thresholds *thresholds) { |
| 302 | value_t *value = p->values; | 320 | smart_value *value = values->values; |
| 303 | threshold_t *threshold = t->thresholds; | 321 | smart_threshold *threshold = thresholds->thresholds; |
| 322 | |||
| 304 | int status = OPERATIONAL; | 323 | int status = OPERATIONAL; |
| 305 | int prefailure = 0; | 324 | int prefailure = 0; |
| 306 | int advisory = 0; | 325 | int advisory = 0; |
| 307 | int failed = 0; | 326 | int failed = 0; |
| 308 | int passed = 0; | 327 | int passed = 0; |
| 309 | int total = 0; | 328 | int total = 0; |
| 310 | int i; | 329 | 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) { | 330 | if (value->id && threshold->id && value->id == threshold->id) { |
| 313 | if (value->value < threshold->threshold) { | 331 | if (value->value < threshold->threshold) { |
| 314 | ++failed; | 332 | ++failed; |
| @@ -327,6 +345,7 @@ int nagios(values_t *p, thresholds_t *t) { | |||
| 327 | ++value; | 345 | ++value; |
| 328 | ++threshold; | 346 | ++threshold; |
| 329 | } | 347 | } |
| 348 | |||
| 330 | switch (status) { | 349 | switch (status) { |
| 331 | case PREFAILURE: | 350 | case PREFAILURE: |
| 332 | printf(_("CRITICAL - %d Harddrive PreFailure%cDetected! %d/%d tests failed.\n"), prefailure, prefailure > 1 ? 's' : ' ', failed, | 351 | printf(_("CRITICAL - %d Harddrive PreFailure%cDetected! %d/%d tests failed.\n"), prefailure, prefailure > 1 ? 's' : ' ', failed, |
| @@ -349,50 +368,51 @@ int nagios(values_t *p, thresholds_t *t) { | |||
| 349 | return status; | 368 | return status; |
| 350 | } | 369 | } |
| 351 | 370 | ||
| 352 | void print_value(value_t *p, threshold_t *t) { | 371 | void print_value(smart_value *value_pointer, smart_threshold *threshold_pointer) { |
| 353 | printf("Id=%3d, Status=%2d {%s , %s}, Value=%3d, Threshold=%3d, %s\n", p->id, p->status, p->status & 1 ? "PreFailure" : "Advisory ", | 372 | printf("Id=%3d, Status=%2d {%s , %s}, Value=%3d, Threshold=%3d, %s\n", value_pointer->id, value_pointer->status, |
| 354 | p->status & 2 ? "OnLine " : "OffLine", p->value, t->threshold, p->value >= t->threshold ? "Passed" : "Failed"); | 373 | value_pointer->status & 1 ? "PreFailure" : "Advisory ", value_pointer->status & 2 ? "OnLine " : "OffLine", |
| 374 | value_pointer->value, threshold_pointer->threshold, value_pointer->value >= threshold_pointer->threshold ? "Passed" : "Failed"); | ||
| 355 | } | 375 | } |
| 356 | 376 | ||
| 357 | void print_values(values_t *p, thresholds_t *t) { | 377 | void print_values(smart_values *values, smart_thresholds *thresholds) { |
| 358 | value_t *value = p->values; | 378 | smart_value *value = values->values; |
| 359 | threshold_t *threshold = t->thresholds; | 379 | smart_threshold *threshold = thresholds->thresholds; |
| 360 | int i; | 380 | for (int i = 0; i < NR_ATTRIBUTES; i++) { |
| 361 | for (i = 0; i < NR_ATTRIBUTES; i++) { | ||
| 362 | if (value->id && threshold->id && value->id == threshold->id) { | 381 | if (value->id && threshold->id && value->id == threshold->id) { |
| 363 | print_value(value++, threshold++); | 382 | print_value(value++, threshold++); |
| 364 | } | 383 | } |
| 365 | } | 384 | } |
| 366 | printf(_("OffLineStatus=%d {%s}, AutoOffLine=%s, OffLineTimeout=%d minutes\n"), p->offline_status, | 385 | printf(_("OffLineStatus=%d {%s}, AutoOffLine=%s, OffLineTimeout=%d minutes\n"), values->offline_status, |
| 367 | get_offline_text(p->offline_status & 0x7f), (p->offline_status & 0x80 ? "Yes" : "No"), p->offline_timeout / 60); | 386 | get_offline_text(values->offline_status & 0x7f), (values->offline_status & 0x80 ? "Yes" : "No"), values->offline_timeout / 60); |
| 368 | printf(_("OffLineCapability=%d {%s %s %s}\n"), p->offline_capability, p->offline_capability & 1 ? "Immediate" : "", | 387 | printf(_("OffLineCapability=%d {%s %s %s}\n"), values->offline_capability, values->offline_capability & 1 ? "Immediate" : "", |
| 369 | p->offline_capability & 2 ? "Auto" : "", p->offline_capability & 4 ? "AbortOnCmd" : "SuspendOnCmd"); | 388 | values->offline_capability & 2 ? "Auto" : "", values->offline_capability & 4 ? "AbortOnCmd" : "SuspendOnCmd"); |
| 370 | printf(_("SmartRevision=%d, CheckSum=%d, SmartCapability=%d {%s %s}\n"), p->revision, p->checksum, p->smart_capability, | 389 | printf(_("SmartRevision=%d, CheckSum=%d, SmartCapability=%d {%s %s}\n"), values->revision, values->checksum, values->smart_capability, |
| 371 | p->smart_capability & 1 ? "SaveOnStandBy" : "", p->smart_capability & 2 ? "AutoSave" : ""); | 390 | values->smart_capability & 1 ? "SaveOnStandBy" : "", values->smart_capability & 2 ? "AutoSave" : ""); |
| 372 | } | 391 | } |
| 373 | 392 | ||
| 374 | int smart_cmd_simple(int fd, enum SmartCommand command, uint8_t val0, bool show_error) { | 393 | mp_state_enum smart_cmd_simple(int file_descriptor, enum SmartCommand command, uint8_t val0, bool show_error) { |
| 375 | int e = STATE_UNKNOWN; | 394 | mp_state_enum result = STATE_UNKNOWN; |
| 376 | #ifdef __linux__ | 395 | #ifdef __linux__ |
| 377 | uint8_t args[4]; | 396 | uint8_t args[4] = { |
| 378 | args[0] = WIN_SMART; | 397 | WIN_SMART, |
| 379 | args[1] = val0; | 398 | val0, |
| 380 | args[2] = smart_command[command].value; | 399 | smart_command[command].value, |
| 381 | args[3] = 0; | 400 | 0, |
| 382 | if (ioctl(fd, HDIO_DRIVE_CMD, &args)) { | 401 | }; |
| 383 | e = STATE_CRITICAL; | 402 | |
| 403 | if (ioctl(file_descriptor, HDIO_DRIVE_CMD, &args)) { | ||
| 404 | result = STATE_CRITICAL; | ||
| 384 | if (show_error) { | 405 | if (show_error) { |
| 385 | printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno)); | 406 | printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno)); |
| 386 | } | 407 | } |
| 387 | } else { | 408 | } else { |
| 388 | e = STATE_OK; | 409 | result = STATE_OK; |
| 389 | if (show_error) { | 410 | if (show_error) { |
| 390 | printf(_("OK - Command sent (%s)\n"), smart_command[command].text); | 411 | printf(_("OK - Command sent (%s)\n"), smart_command[command].text); |
| 391 | } | 412 | } |
| 392 | } | 413 | } |
| 393 | 414 | ||
| 394 | #endif /* __linux__ */ | 415 | #elif defined __NetBSD__ |
| 395 | #ifdef __NetBSD__ | ||
| 396 | struct atareq req; | 416 | struct atareq req; |
| 397 | 417 | ||
| 398 | memset(&req, 0, sizeof(req)); | 418 | memset(&req, 0, sizeof(req)); |
| @@ -403,7 +423,7 @@ int smart_cmd_simple(int fd, enum SmartCommand command, uint8_t val0, bool show_ | |||
| 403 | req.cylinder = WDSMART_CYL; | 423 | req.cylinder = WDSMART_CYL; |
| 404 | req.sec_count = val0; | 424 | req.sec_count = val0; |
| 405 | 425 | ||
| 406 | if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { | 426 | if (ioctl(file_descriptor, ATAIOCCOMMAND, &req) == 0) { |
| 407 | if (req.retsts != ATACMD_OK) { | 427 | if (req.retsts != ATACMD_OK) { |
| 408 | errno = ENODEV; | 428 | errno = ENODEV; |
| 409 | } | 429 | } |
| @@ -413,42 +433,42 @@ int smart_cmd_simple(int fd, enum SmartCommand command, uint8_t val0, bool show_ | |||
| 413 | } | 433 | } |
| 414 | 434 | ||
| 415 | if (errno != 0) { | 435 | if (errno != 0) { |
| 416 | e = STATE_CRITICAL; | 436 | result = STATE_CRITICAL; |
| 417 | if (show_error) { | 437 | if (show_error) { |
| 418 | printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno)); | 438 | printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno)); |
| 419 | } | 439 | } |
| 420 | } else { | 440 | } else { |
| 421 | e = STATE_OK; | 441 | result = STATE_OK; |
| 422 | if (show_error) { | 442 | if (show_error) { |
| 423 | printf(_("OK - Command sent (%s)\n"), smart_command[command].text); | 443 | printf(_("OK - Command sent (%s)\n"), smart_command[command].text); |
| 424 | } | 444 | } |
| 425 | } | 445 | } |
| 426 | 446 | #else | |
| 447 | # error Not implemented for this OS | ||
| 427 | #endif /* __NetBSD__ */ | 448 | #endif /* __NetBSD__ */ |
| 428 | return e; | 449 | |
| 450 | return result; | ||
| 429 | } | 451 | } |
| 430 | 452 | ||
| 431 | int smart_read_thresholds(int fd, thresholds_t *thresholds) { | 453 | int smart_read_thresholds(int file_descriptor, smart_thresholds *thresholds) { |
| 432 | #ifdef __linux__ | 454 | #ifdef __linux__ |
| 433 | int e; | ||
| 434 | uint8_t args[4 + 512]; | 455 | uint8_t args[4 + 512]; |
| 435 | args[0] = WIN_SMART; | 456 | args[0] = WIN_SMART; |
| 436 | args[1] = 0; | 457 | args[1] = 0; |
| 437 | args[2] = SMART_READ_THRESHOLDS; | 458 | args[2] = SMART_READ_THRESHOLDS; |
| 438 | args[3] = 1; | 459 | args[3] = 1; |
| 439 | if (ioctl(fd, HDIO_DRIVE_CMD, &args)) { | 460 | if (ioctl(file_descriptor, HDIO_DRIVE_CMD, &args)) { |
| 440 | e = errno; | 461 | int errno_storage = errno; |
| 441 | printf(_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror(errno)); | 462 | printf(_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror(errno)); |
| 442 | return e; | 463 | return errno_storage; |
| 443 | } | 464 | } |
| 444 | memcpy(thresholds, args + 4, 512); | 465 | memcpy(thresholds, args + 4, 512); |
| 445 | #endif /* __linux__ */ | 466 | #elif defined __NetBSD__ |
| 446 | #ifdef __NetBSD__ | ||
| 447 | struct atareq req; | 467 | struct atareq req; |
| 448 | unsigned char inbuf[DEV_BSIZE]; | ||
| 449 | |||
| 450 | memset(&req, 0, sizeof(req)); | 468 | memset(&req, 0, sizeof(req)); |
| 451 | req.timeout = 1000; | 469 | req.timeout = 1000; |
| 470 | |||
| 471 | unsigned char inbuf[DEV_BSIZE]; | ||
| 452 | memset(&inbuf, 0, sizeof(inbuf)); | 472 | memset(&inbuf, 0, sizeof(inbuf)); |
| 453 | 473 | ||
| 454 | req.flags = ATACMD_READ; | 474 | req.flags = ATACMD_READ; |
| @@ -458,20 +478,23 @@ int smart_read_thresholds(int fd, thresholds_t *thresholds) { | |||
| 458 | req.datalen = sizeof(inbuf); | 478 | req.datalen = sizeof(inbuf); |
| 459 | req.cylinder = WDSMART_CYL; | 479 | req.cylinder = WDSMART_CYL; |
| 460 | 480 | ||
| 461 | if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { | 481 | if (ioctl(file_descriptor, ATAIOCCOMMAND, &req) == 0) { |
| 462 | if (req.retsts != ATACMD_OK) { | 482 | if (req.retsts != ATACMD_OK) { |
| 463 | errno = ENODEV; | 483 | errno = ENODEV; |
| 464 | } | 484 | } |
| 465 | } | 485 | } |
| 466 | 486 | ||
| 467 | if (errno != 0) { | 487 | if (errno != 0) { |
| 468 | int e = errno; | 488 | int errno_storage = errno; |
| 469 | printf(_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror(errno)); | 489 | printf(_("CRITICAL - SMART_READ_THRESHOLDS: %s\n"), strerror(errno)); |
| 470 | return e; | 490 | return errno_storage; |
| 471 | } | 491 | } |
| 472 | 492 | ||
| 473 | (void)memcpy(thresholds, inbuf, 512); | 493 | (void)memcpy(thresholds, inbuf, 512); |
| 494 | #else | ||
| 495 | # error Not implemented for this OS | ||
| 474 | #endif /* __NetBSD__ */ | 496 | #endif /* __NetBSD__ */ |
| 497 | |||
| 475 | return 0; | 498 | return 0; |
| 476 | } | 499 | } |
| 477 | 500 | ||
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 | |||
| 6 | typedef struct { | ||
| 7 | char *device; | ||
| 8 | } check_ide_smart_config; | ||
| 9 | |||
| 10 | check_ide_smart_config check_ide_smart_init() { | ||
| 11 | check_ide_smart_config tmp = { | ||
| 12 | .device = NULL, | ||
| 13 | }; | ||
| 14 | return tmp; | ||
| 15 | } | ||
