diff options
Diffstat (limited to 'plugins/check_swap.c')
| -rw-r--r-- | plugins/check_swap.c | 191 |
1 files changed, 96 insertions, 95 deletions
diff --git a/plugins/check_swap.c b/plugins/check_swap.c index f34b0514..4e3471b6 100644 --- a/plugins/check_swap.c +++ b/plugins/check_swap.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * | 4 | * |
| 5 | * License: GPL | 5 | * License: GPL |
| 6 | * Copyright (c) 2000 Karl DeBisschop (kdebisschop@users.sourceforge.net) | 6 | * Copyright (c) 2000 Karl DeBisschop (kdebisschop@users.sourceforge.net) |
| 7 | * Copyright (c) 2000-2023 Monitoring Plugins Development Team | 7 | * Copyright (c) 2000-2024 Monitoring Plugins Development Team |
| 8 | * | 8 | * |
| 9 | * Description: | 9 | * Description: |
| 10 | * | 10 | * |
| @@ -27,21 +27,21 @@ | |||
| 27 | * | 27 | * |
| 28 | *****************************************************************************/ | 28 | *****************************************************************************/ |
| 29 | 29 | ||
| 30 | #include <stdint.h> | ||
| 30 | const char *progname = "check_swap"; | 31 | const char *progname = "check_swap"; |
| 31 | const char *copyright = "2000-2023"; | 32 | const char *copyright = "2000-2024"; |
| 32 | const char *email = "devel@monitoring-plugins.org"; | 33 | const char *email = "devel@monitoring-plugins.org"; |
| 33 | 34 | ||
| 34 | |||
| 35 | #ifdef HAVE_DECL_SWAPCTL | 35 | #ifdef HAVE_DECL_SWAPCTL |
| 36 | #ifdef HAVE_SYS_PARAM_H | 36 | # ifdef HAVE_SYS_PARAM_H |
| 37 | #include <sys/param.h> | 37 | # include <sys/param.h> |
| 38 | #endif | 38 | # endif |
| 39 | #ifdef HAVE_SYS_SWAP_H | 39 | # ifdef HAVE_SYS_SWAP_H |
| 40 | #include <sys/swap.h> | 40 | # include <sys/swap.h> |
| 41 | #endif | 41 | # endif |
| 42 | #ifdef HAVE_SYS_STAT_H | 42 | # ifdef HAVE_SYS_STAT_H |
| 43 | #include <sys/stat.h> | 43 | # include <sys/stat.h> |
| 44 | #endif | 44 | # endif |
| 45 | #endif | 45 | #endif |
| 46 | 46 | ||
| 47 | #include "./check_swap.d/check_swap.h" | 47 | #include "./check_swap.d/check_swap.h" |
| @@ -52,11 +52,13 @@ typedef struct { | |||
| 52 | swap_config config; | 52 | swap_config config; |
| 53 | } swap_config_wrapper; | 53 | } swap_config_wrapper; |
| 54 | 54 | ||
| 55 | swap_config_wrapper process_arguments(swap_config_wrapper config, int argc, | 55 | static swap_config_wrapper process_arguments(int argc, char **argv); |
| 56 | char **argv); | 56 | void print_usage(void); |
| 57 | void print_usage(); | 57 | static void print_help(swap_config /*config*/); |
| 58 | void print_help(swap_config); | ||
| 59 | 58 | ||
| 59 | static int verbose; | ||
| 60 | |||
| 61 | #define HUNDRED_PERCENT 100 | ||
| 60 | 62 | ||
| 61 | int main(int argc, char **argv) { | 63 | int main(int argc, char **argv) { |
| 62 | setlocale(LC_ALL, ""); | 64 | setlocale(LC_ALL, ""); |
| @@ -69,11 +71,7 @@ int main(int argc, char **argv) { | |||
| 69 | /* Parse extra opts if any */ | 71 | /* Parse extra opts if any */ |
| 70 | argv = np_extra_opts(&argc, argv, progname); | 72 | argv = np_extra_opts(&argc, argv, progname); |
| 71 | 73 | ||
| 72 | swap_config_wrapper tmp = {.errorcode = OK}; | 74 | swap_config_wrapper tmp = process_arguments(argc, argv); |
| 73 | |||
| 74 | tmp.config = swap_config_init(); | ||
| 75 | |||
| 76 | tmp = process_arguments(tmp, argc, argv); | ||
| 77 | 75 | ||
| 78 | if (tmp.errorcode != OK) { | 76 | if (tmp.errorcode != OK) { |
| 79 | usage4(_("Could not parse arguments")); | 77 | usage4(_("Could not parse arguments")); |
| @@ -87,8 +85,7 @@ int main(int argc, char **argv) { | |||
| 87 | 85 | ||
| 88 | /* if total_swap_mb == 0, let's not divide by 0 */ | 86 | /* if total_swap_mb == 0, let's not divide by 0 */ |
| 89 | if (data.metrics.total != 0) { | 87 | if (data.metrics.total != 0) { |
| 90 | percent_used = | 88 | percent_used = HUNDRED_PERCENT * ((double)data.metrics.used) / ((double)data.metrics.total); |
| 91 | 100 * ((double)data.metrics.used) / ((double)data.metrics.total); | ||
| 92 | } else { | 89 | } else { |
| 93 | printf(_("SWAP %s - Swap is either disabled, not present, or of zero " | 90 | printf(_("SWAP %s - Swap is either disabled, not present, or of zero " |
| 94 | "size."), | 91 | "size."), |
| @@ -96,77 +93,97 @@ int main(int argc, char **argv) { | |||
| 96 | exit(config.no_swap_state); | 93 | exit(config.no_swap_state); |
| 97 | } | 94 | } |
| 98 | 95 | ||
| 99 | if (config.verbose) { | 96 | if (verbose) { |
| 100 | printf("Computed usage percentage: %g\n", percent_used); | 97 | printf("Computed usage percentage: %g\n", percent_used); |
| 101 | } | 98 | } |
| 102 | 99 | ||
| 103 | uint64_t warn_print = config.warn.value; | 100 | uint64_t warn_print = config.warn.value; |
| 104 | if (config.warn.is_percentage) { | 101 | if (config.warn.is_percentage) { |
| 105 | warn_print = config.warn.value * (data.metrics.total / 100); | 102 | warn_print = config.warn.value * (data.metrics.total / HUNDRED_PERCENT); |
| 106 | } | 103 | } |
| 107 | 104 | ||
| 108 | uint64_t crit_print = config.crit.value; | 105 | uint64_t crit_print = config.crit.value; |
| 109 | if (config.crit.is_percentage) { | 106 | if (config.crit.is_percentage) { |
| 110 | crit_print = config.crit.value * (data.metrics.total / 100); | 107 | crit_print = config.crit.value * (data.metrics.total / HUNDRED_PERCENT); |
| 111 | } | 108 | } |
| 112 | 109 | ||
| 113 | char *perfdata = | 110 | char *perfdata = perfdata_uint64("swap", data.metrics.free, "B", true, warn_print, true, crit_print, true, 0, true, data.metrics.total); |
| 114 | perfdata_uint64("swap", data.metrics.free, "B", true, warn_print, true, | ||
| 115 | crit_print, true, 0, true, (long)data.metrics.total); | ||
| 116 | 111 | ||
| 117 | if (config.verbose > 1) { | 112 | if (verbose > 1) { |
| 118 | printf("Warn threshold value: %" PRIu64 "\n", config.warn.value); | 113 | printf("Warn threshold value: %" PRIu64 "\n", config.warn.value); |
| 119 | } | 114 | } |
| 120 | 115 | ||
| 121 | if ((config.warn.is_percentage && | 116 | if ((config.warn.is_percentage && (percent_used >= (double)(HUNDRED_PERCENT - config.warn.value))) || |
| 122 | (percent_used >= (100 - config.warn.value))) || | ||
| 123 | config.warn.value >= data.metrics.free) { | 117 | config.warn.value >= data.metrics.free) { |
| 124 | data.statusCode = max_state(data.statusCode, STATE_WARNING); | 118 | data.statusCode = max_state(data.statusCode, STATE_WARNING); |
| 125 | } | 119 | } |
| 126 | 120 | ||
| 127 | if (config.verbose > 1) { | 121 | if (verbose > 1) { |
| 128 | printf("Crit threshold value: %" PRIu64 "\n", config.crit.value); | 122 | printf("Crit threshold value: %" PRIu64 "\n", config.crit.value); |
| 129 | } | 123 | } |
| 130 | 124 | ||
| 131 | if ((config.crit.is_percentage && | 125 | if ((config.crit.is_percentage && (percent_used >= (double)(HUNDRED_PERCENT - config.crit.value))) || |
| 132 | (percent_used >= (100 - config.crit.value))) || | ||
| 133 | config.crit.value >= data.metrics.free) { | 126 | config.crit.value >= data.metrics.free) { |
| 134 | data.statusCode = max_state(data.statusCode, STATE_CRITICAL); | 127 | data.statusCode = max_state(data.statusCode, STATE_CRITICAL); |
| 135 | } | 128 | } |
| 136 | 129 | ||
| 137 | printf(_("SWAP %s - %g%% free (%lluMB out of %lluMB) %s|%s\n"), | 130 | printf(_("SWAP %s - %g%% free (%lluMB out of %lluMB) %s|%s\n"), state_text(data.statusCode), (HUNDRED_PERCENT - percent_used), |
| 138 | state_text(data.statusCode), (100 - percent_used), data.metrics.free, | 131 | data.metrics.free, data.metrics.total, status, perfdata); |
| 139 | data.metrics.total, status, perfdata); | ||
| 140 | 132 | ||
| 141 | exit(data.statusCode); | 133 | exit(data.statusCode); |
| 142 | } | 134 | } |
| 143 | 135 | ||
| 136 | int check_swap(float free_swap_mb, float total_swap_mb, swap_config config) { | ||
| 137 | if (total_swap_mb == 0) { | ||
| 138 | return config.no_swap_state; | ||
| 139 | } | ||
| 140 | |||
| 141 | uint64_t free_swap = (uint64_t)(free_swap_mb * (1024 * 1024)); /* Convert back to bytes as warn and crit specified in bytes */ | ||
| 142 | |||
| 143 | if (!config.crit.is_percentage && config.crit.value >= free_swap) { | ||
| 144 | return STATE_CRITICAL; | ||
| 145 | } | ||
| 146 | if (!config.warn.is_percentage && config.warn.value >= free_swap) { | ||
| 147 | return STATE_WARNING; | ||
| 148 | } | ||
| 149 | |||
| 150 | uint64_t usage_percentage = (uint64_t)((total_swap_mb - free_swap_mb) / total_swap_mb) * HUNDRED_PERCENT; | ||
| 151 | |||
| 152 | if (config.crit.is_percentage && config.crit.value != 0 && usage_percentage >= (HUNDRED_PERCENT - config.crit.value)) { | ||
| 153 | return STATE_CRITICAL; | ||
| 154 | } | ||
| 155 | |||
| 156 | if (config.warn.is_percentage && config.warn.value != 0 && usage_percentage >= (HUNDRED_PERCENT - config.warn.value)) { | ||
| 157 | return STATE_WARNING; | ||
| 158 | } | ||
| 159 | |||
| 160 | return STATE_OK; | ||
| 161 | } | ||
| 162 | |||
| 144 | /* process command-line arguments */ | 163 | /* process command-line arguments */ |
| 145 | swap_config_wrapper process_arguments(swap_config_wrapper conf_wrapper, | 164 | swap_config_wrapper process_arguments(int argc, char **argv) { |
| 146 | int argc, char **argv) { | 165 | swap_config_wrapper conf_wrapper = {.errorcode = OK}; |
| 166 | conf_wrapper.config = swap_config_init(); | ||
| 167 | |||
| 147 | if (argc < 2) { | 168 | if (argc < 2) { |
| 148 | conf_wrapper.errorcode = ERROR; | 169 | conf_wrapper.errorcode = ERROR; |
| 149 | return conf_wrapper; | 170 | return conf_wrapper; |
| 150 | } | 171 | } |
| 151 | 172 | ||
| 152 | int option = 0; | 173 | static struct option longopts[] = {{"warning", required_argument, 0, 'w'}, {"critical", required_argument, 0, 'c'}, |
| 153 | static struct option longopts[] = {{"warning", required_argument, 0, 'w'}, | 174 | {"allswaps", no_argument, 0, 'a'}, {"no-swap", required_argument, 0, 'n'}, |
| 154 | {"critical", required_argument, 0, 'c'}, | 175 | {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, |
| 155 | {"allswaps", no_argument, 0, 'a'}, | 176 | {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; |
| 156 | {"no-swap", required_argument, 0, 'n'}, | 177 | |
| 157 | {"verbose", no_argument, 0, 'v'}, | ||
| 158 | {"version", no_argument, 0, 'V'}, | ||
| 159 | {"help", no_argument, 0, 'h'}, | ||
| 160 | {0, 0, 0, 0}}; | ||
| 161 | |||
| 162 | int c = 0; /* option character */ | ||
| 163 | while (true) { | 178 | while (true) { |
| 164 | c = getopt_long(argc, argv, "+?Vvhac:w:n:", longopts, &option); | 179 | int option = 0; |
| 180 | int option_char = getopt_long(argc, argv, "+?Vvhac:w:n:", longopts, &option); | ||
| 165 | 181 | ||
| 166 | if (c == -1 || c == EOF) | 182 | if (option_char == -1 || option_char == EOF) { |
| 167 | break; | 183 | break; |
| 184 | } | ||
| 168 | 185 | ||
| 169 | switch (c) { | 186 | switch (option_char) { |
| 170 | case 'w': /* warning size threshold */ | 187 | case 'w': /* warning size threshold */ |
| 171 | { | 188 | { |
| 172 | /* | 189 | /* |
| @@ -183,22 +200,18 @@ swap_config_wrapper process_arguments(swap_config_wrapper conf_wrapper, | |||
| 183 | conf_wrapper.config.warn.is_percentage = true; | 200 | conf_wrapper.config.warn.is_percentage = true; |
| 184 | optarg[length - 1] = '\0'; | 201 | optarg[length - 1] = '\0'; |
| 185 | if (is_uint64(optarg, &conf_wrapper.config.warn.value)) { | 202 | if (is_uint64(optarg, &conf_wrapper.config.warn.value)) { |
| 186 | if (conf_wrapper.config.warn.value > 100) { | 203 | if (conf_wrapper.config.warn.value > HUNDRED_PERCENT) { |
| 187 | usage4( | 204 | usage4(_("Warning threshold percentage must be <= 100!")); |
| 188 | _("Warning threshold percentage must be <= 100!")); | ||
| 189 | } | 205 | } |
| 190 | } | 206 | } |
| 191 | break; | 207 | break; |
| 192 | } else { | 208 | } /* It's Bytes */ |
| 193 | /* It's Bytes */ | 209 | conf_wrapper.config.warn.is_percentage = false; |
| 194 | conf_wrapper.config.warn.is_percentage = false; | 210 | if (is_uint64(optarg, &conf_wrapper.config.warn.value)) { |
| 195 | if (is_uint64(optarg, &conf_wrapper.config.warn.value)) { | 211 | break; |
| 196 | break; | ||
| 197 | } else { | ||
| 198 | usage4(_("Warning threshold be positive integer or " | ||
| 199 | "percentage!")); | ||
| 200 | } | ||
| 201 | } | 212 | } |
| 213 | usage4(_("Warning threshold be positive integer or " | ||
| 214 | "percentage!")); | ||
| 202 | } | 215 | } |
| 203 | case 'c': /* critical size threshold */ | 216 | case 'c': /* critical size threshold */ |
| 204 | { | 217 | { |
| @@ -216,35 +229,30 @@ swap_config_wrapper process_arguments(swap_config_wrapper conf_wrapper, | |||
| 216 | conf_wrapper.config.crit.is_percentage = true; | 229 | conf_wrapper.config.crit.is_percentage = true; |
| 217 | optarg[length - 1] = '\0'; | 230 | optarg[length - 1] = '\0'; |
| 218 | if (is_uint64(optarg, &conf_wrapper.config.crit.value)) { | 231 | if (is_uint64(optarg, &conf_wrapper.config.crit.value)) { |
| 219 | if (conf_wrapper.config.crit.value > 100) { | 232 | if (conf_wrapper.config.crit.value > HUNDRED_PERCENT) { |
| 220 | usage4( | 233 | usage4(_("Critical threshold percentage must be <= 100!")); |
| 221 | _("Critical threshold percentage must be <= 100!")); | ||
| 222 | } | 234 | } |
| 223 | } | 235 | } |
| 224 | break; | 236 | break; |
| 225 | } else { | 237 | } /* It's Bytes */ |
| 226 | /* It's Bytes */ | 238 | conf_wrapper.config.crit.is_percentage = false; |
| 227 | conf_wrapper.config.crit.is_percentage = false; | 239 | if (is_uint64(optarg, &conf_wrapper.config.crit.value)) { |
| 228 | if (is_uint64(optarg, &conf_wrapper.config.crit.value)) { | 240 | break; |
| 229 | break; | ||
| 230 | } else { | ||
| 231 | usage4(_("Critical threshold be positive integer or " | ||
| 232 | "percentage!")); | ||
| 233 | } | ||
| 234 | } | 241 | } |
| 242 | usage4(_("Critical threshold be positive integer or " | ||
| 243 | "percentage!")); | ||
| 235 | } | 244 | } |
| 236 | case 'a': /* all swap */ | 245 | case 'a': /* all swap */ |
| 237 | conf_wrapper.config.allswaps = true; | 246 | conf_wrapper.config.allswaps = true; |
| 238 | break; | 247 | break; |
| 239 | case 'n': | 248 | case 'n': |
| 240 | if ((conf_wrapper.config.no_swap_state = | 249 | if ((conf_wrapper.config.no_swap_state = mp_translate_state(optarg)) == ERROR) { |
| 241 | mp_translate_state(optarg)) == ERROR) { | ||
| 242 | usage4(_("no-swap result must be a valid state name (OK, " | 250 | usage4(_("no-swap result must be a valid state name (OK, " |
| 243 | "WARNING, CRITICAL, UNKNOWN) or integer (0-3).")); | 251 | "WARNING, CRITICAL, UNKNOWN) or integer (0-3).")); |
| 244 | } | 252 | } |
| 245 | break; | 253 | break; |
| 246 | case 'v': /* verbose */ | 254 | case 'v': /* verbose */ |
| 247 | conf_wrapper.config.verbose++; | 255 | verbose++; |
| 248 | break; | 256 | break; |
| 249 | case 'V': /* version */ | 257 | case 'V': /* version */ |
| 250 | print_revision(progname, NP_VERSION); | 258 | print_revision(progname, NP_VERSION); |
| @@ -257,16 +265,12 @@ swap_config_wrapper process_arguments(swap_config_wrapper conf_wrapper, | |||
| 257 | } | 265 | } |
| 258 | } | 266 | } |
| 259 | 267 | ||
| 260 | c = optind; | 268 | if (conf_wrapper.config.warn.value == 0 && conf_wrapper.config.crit.value == 0) { |
| 261 | |||
| 262 | if (conf_wrapper.config.warn.value == 0 && | ||
| 263 | conf_wrapper.config.crit.value == 0) { | ||
| 264 | conf_wrapper.errorcode = ERROR; | 269 | conf_wrapper.errorcode = ERROR; |
| 265 | return conf_wrapper; | 270 | return conf_wrapper; |
| 266 | } else if ((conf_wrapper.config.warn.is_percentage == | 271 | } |
| 267 | conf_wrapper.config.crit.is_percentage) && | 272 | if ((conf_wrapper.config.warn.is_percentage == conf_wrapper.config.crit.is_percentage) && |
| 268 | (conf_wrapper.config.warn.value < | 273 | (conf_wrapper.config.warn.value < conf_wrapper.config.crit.value)) { |
| 269 | conf_wrapper.config.crit.value)) { | ||
| 270 | /* This is NOT triggered if warn and crit are different units, e.g warn | 274 | /* This is NOT triggered if warn and crit are different units, e.g warn |
| 271 | * is percentage and crit is absolute. We cannot determine the condition | 275 | * is percentage and crit is absolute. We cannot determine the condition |
| 272 | * at this point since we dont know the value of total swap yet | 276 | * at this point since we dont know the value of total swap yet |
| @@ -304,8 +308,7 @@ void print_help(swap_config config) { | |||
| 304 | printf(" %s\n", _("Exit with CRITICAL status if less than PERCENT of " | 308 | printf(" %s\n", _("Exit with CRITICAL status if less than PERCENT of " |
| 305 | "swap space is free")); | 309 | "swap space is free")); |
| 306 | printf(" %s\n", "-a, --allswaps"); | 310 | printf(" %s\n", "-a, --allswaps"); |
| 307 | printf(" %s\n", | 311 | printf(" %s\n", _("Conduct comparisons for all swap partitions, one by one")); |
| 308 | _("Conduct comparisons for all swap partitions, one by one")); | ||
| 309 | printf(" %s\n", "-n, --no-swap=<ok|warning|critical|unknown>"); | 312 | printf(" %s\n", "-n, --no-swap=<ok|warning|critical|unknown>"); |
| 310 | printf(" %s %s\n", | 313 | printf(" %s %s\n", |
| 311 | _("Resulting state when there is no swap regardless of thresholds. " | 314 | _("Resulting state when there is no swap regardless of thresholds. " |
| @@ -317,14 +320,12 @@ void print_help(swap_config config) { | |||
| 317 | printf("%s\n", _("Notes:")); | 320 | printf("%s\n", _("Notes:")); |
| 318 | printf(" %s\n", _("Both INTEGER and PERCENT thresholds can be specified, " | 321 | printf(" %s\n", _("Both INTEGER and PERCENT thresholds can be specified, " |
| 319 | "they are all checked.")); | 322 | "they are all checked.")); |
| 320 | printf( | 323 | printf(" %s\n", _("On AIX, if -a is specified, uses lsps -a, otherwise uses lsps -s.")); |
| 321 | " %s\n", | ||
| 322 | _("On AIX, if -a is specified, uses lsps -a, otherwise uses lsps -s.")); | ||
| 323 | 324 | ||
| 324 | printf(UT_SUPPORT); | 325 | printf(UT_SUPPORT); |
| 325 | } | 326 | } |
| 326 | 327 | ||
| 327 | void print_usage() { | 328 | void print_usage(void) { |
| 328 | printf("%s\n", _("Usage:")); | 329 | printf("%s\n", _("Usage:")); |
| 329 | printf(" %s [-av] -w <percent_free>%% -c <percent_free>%%\n", progname); | 330 | printf(" %s [-av] -w <percent_free>%% -c <percent_free>%%\n", progname); |
| 330 | printf(" -w <bytes_free> -c <bytes_free> [-n <state>]\n"); | 331 | printf(" -w <bytes_free> -c <bytes_free> [-n <state>]\n"); |
