diff options
author | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2024-11-02 13:37:39 +0100 |
---|---|---|
committer | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2024-11-02 13:37:39 +0100 |
commit | 3faeed07c4825d5c3ceb323e814e703d9262cd82 (patch) | |
tree | b6a61e24ffa0fbb4af5f145c137f1f584aaba1bc /plugins/check_swap.c | |
parent | 735b04eff721a28e791714c0da4c8ac5726bfbcf (diff) | |
parent | 6d1d1dac32841d5ca6ee51bb09b30a6c604b17e2 (diff) | |
download | monitoring-plugins-3faeed07c4825d5c3ceb323e814e703d9262cd82.tar.gz |
Merge branch 'master' into check_swap_again
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"); |