ca8442a416c28bb501a86de2447aca2bb1eda03d
1 /******************************************************************************
2 *
3 * CHECK_SWAP.C
4 *
5 * Program: Process plugin for Nagios
6 * License: GPL
7 * Copyright (c) 2000 Karl DeBisschop (kdebisschop@users.sourceforge.net)
8 *
9 * $Id$
10 *
11 ******************************************************************************/
13 #include "common.h"
14 #include "popen.h"
15 #include "utils.h"
17 #define PROGNAME "check_swap"
19 int process_arguments (int argc, char **argv);
20 int call_getopt (int argc, char **argv);
21 int validate_arguments (void);
22 void print_usage (void);
23 void print_help (void);
25 int warn_percent = 200, crit_percent = 200, warn_size = -1, crit_size = -1;
27 int
28 main (int argc, char **argv)
29 {
30 int total_swap, used_swap, free_swap, percent_used;
31 int result = STATE_OK;
32 char input_buffer[MAX_INPUT_BUFFER];
33 #ifdef HAVE_SWAP
34 char *temp_buffer;
35 #endif
36 #ifdef HAVE_PROC_MEMINFO
37 FILE *fp;
38 #endif
39 char str[32];
40 char *status = NULL;
42 if (process_arguments (argc, argv) != OK)
43 usage ("Invalid command arguments supplied\n");
45 #ifdef HAVE_PROC_MEMINFO
46 fp = fopen (PROC_MEMINFO, "r");
47 status = ssprintf (status, "%s", "Swap used:");
48 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
49 sscanf (input_buffer, " %s %d %d %d", str, &total_swap, &used_swap,
50 &free_swap);
51 if (strstr (str, "Swap")) {
52 percent_used = 100 * (((float) used_swap) / ((float) total_swap));
53 status = ssprintf
54 (status,
55 "%s %2d%% (%d bytes out of %d)",
56 status, percent_used, used_swap, total_swap);
57 if (percent_used >= crit_percent || free_swap <= crit_size)
58 result = STATE_CRITICAL;
59 else if (percent_used >= warn_percent || free_swap <= warn_size)
60 result = STATE_WARNING;
61 break;
62 }
63 }
64 fclose (fp);
65 #else
66 #ifdef HAVE_SWAP
67 child_process = spopen (SWAP_COMMAND);
68 if (child_process == NULL) {
69 printf ("Could not open pipe: %s\n", SWAP_COMMAND);
70 return STATE_UNKNOWN;
71 }
73 child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
74 if (child_stderr == NULL)
75 printf ("Could not open stderr for %s\n", SWAP_COMMAND);
77 sprintf (str, "%s", "");
78 /* read 1st line */
79 fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process);
80 if (strcmp (SWAP_FORMAT, "") == 0) {
81 temp_buffer = strtok (input_buffer, " \n");
82 while (temp_buffer) {
83 if (strstr (temp_buffer, "blocks"))
84 sprintf (str, "%s %s", str, "%f");
85 else if (strstr (temp_buffer, "free"))
86 sprintf (str, "%s %s", str, "%f");
87 else
88 sprintf (str, "%s %s", str, "%*s");
89 temp_buffer = strtok (NULL, " \n");
90 }
91 }
93 status = ssprintf (status, "%s", "Swap used:");
94 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
95 sscanf (input_buffer, SWAP_FORMAT, &total_swap, &free_swap);
96 used_swap = total_swap - free_swap;
97 percent_used = 100 * ((float) used_swap) / ((float) total_swap);
98 status = ssprintf
99 (status,
100 "%s %2d%% (%d bytes out of %d)",
101 status, percent_used, used_swap, total_swap);
102 if (percent_used >= crit_percent || free_swap <= crit_size)
103 result = STATE_CRITICAL;
104 else if (percent_used >= warn_percent || free_swap <= warn_size)
105 result = STATE_WARNING;
106 }
108 /* If we get anything on STDERR, at least set warning */
109 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr))
110 result = max (result, STATE_WARNING);
112 /* close stderr */
113 (void) fclose (child_stderr);
115 /* close the pipe */
116 if (spclose (child_process))
117 result = max (result, STATE_WARNING);
118 #endif
119 #endif
121 #ifndef SWAP_COMMAND
122 #ifndef SWAP_FILE
123 #ifndef HAVE_PROC_MEMINFO
124 return STATE_UNKNOWN;
125 #endif
126 #endif
127 #endif
129 if (result == STATE_OK)
130 printf ("Swap ok - %s\n", status);
131 else if (result == STATE_CRITICAL)
132 printf ("CRITICAL - %s\n", status);
133 else if (result == STATE_WARNING)
134 printf ("WARNING - %s\n", status);
135 else if (result == STATE_UNKNOWN)
136 printf ("Unable to read output\n");
137 else {
138 result = STATE_UNKNOWN;
139 printf ("UNKNOWN - %s\n", status);
140 }
142 return result;
143 }
149 /* process command-line arguments */
150 int
151 process_arguments (int argc, char **argv)
152 {
153 int c, i = 0;
155 #ifdef HAVE_GETOPT_H
156 int option_index = 0;
157 static struct option long_options[] = {
158 {"warning", required_argument, 0, 'w'},
159 {"critical", required_argument, 0, 'c'},
160 {"verbose", no_argument, 0, 'v'},
161 {"version", no_argument, 0, 'V'},
162 {"help", no_argument, 0, 'h'},
163 {0, 0, 0, 0}
164 };
165 #endif
167 if (argc < 2)
168 return ERROR;
170 while (1) {
171 #ifdef HAVE_GETOPT_H
172 c = getopt_long (argc, argv, "+?Vhc:w:", long_options, &option_index);
173 #else
174 c = getopt (argc, argv, "+?Vhc:w:");
175 #endif
177 if (c == -1 || c == EOF)
178 break;
180 switch (c) {
181 case 'w': /* warning time threshold */
182 if (is_intnonneg (optarg)) {
183 warn_size = atoi (optarg);
184 break;
185 }
186 else if (strstr (optarg, ",") &&
187 strstr (optarg, "%") &&
188 sscanf (optarg, "%d,%d%%", &warn_size, &warn_percent) == 2) {
189 break;
190 }
191 else if (strstr (optarg, "%") &&
192 sscanf (optarg, "%d%%", &warn_percent) == 1) {
193 break;
194 }
195 else {
196 usage ("Warning threshold must be integer or percentage!\n");
197 }
198 case 'c': /* critical time threshold */
199 if (is_intnonneg (optarg)) {
200 crit_size = atoi (optarg);
201 break;
202 }
203 else if (strstr (optarg, ",") &&
204 strstr (optarg, "%") &&
205 sscanf (optarg, "%d,%d%%", &crit_size, &crit_percent) == 2) {
206 break;
207 }
208 else if (strstr (optarg, "%") &&
209 sscanf (optarg, "%d%%", &crit_percent) == 1) {
210 break;
211 }
212 else {
213 usage ("Critical threshold must be integer or percentage!\n");
214 }
215 case 'V': /* version */
216 print_revision (my_basename (argv[0]), "$Revision$");
217 exit (STATE_OK);
218 case 'h': /* help */
219 print_help ();
220 exit (STATE_OK);
221 case '?': /* help */
222 usage ("Invalid argument\n");
223 }
224 }
226 c = optind;
227 if (c == argc)
228 return validate_arguments ();
229 if (warn_percent > 100 && is_intnonneg (argv[c]))
230 warn_percent = atoi (argv[c++]);
232 if (c == argc)
233 return validate_arguments ();
234 if (crit_percent > 100 && is_intnonneg (argv[c]))
235 crit_percent = atoi (argv[c++]);
237 if (c == argc)
238 return validate_arguments ();
239 if (warn_size < 0 && is_intnonneg (argv[c]))
240 warn_size = atoi (argv[c++]);
242 if (c == argc)
243 return validate_arguments ();
244 if (crit_size < 0 && is_intnonneg (argv[c]))
245 crit_size = atoi (argv[c++]);
247 return validate_arguments ();
248 }
254 int
255 validate_arguments (void)
256 {
257 if (warn_percent > 100 && crit_percent > 100 && warn_size < 0
258 && crit_size < 0) {
259 return ERROR;
260 }
261 else if (warn_percent > crit_percent) {
262 usage
263 ("Warning percentage should not be less than critical percentage\n");
264 }
265 else if (warn_size < crit_size) {
266 usage
267 ("Warning free space should not be more than critical free space\n");
268 }
269 return OK;
270 }
276 void
277 print_usage (void)
278 {
279 printf
280 ("Usage: check_swap -w <used_percentage>%% -c <used_percentage>%%\n"
281 " check_swap -w <bytes_free> -c <bytes_free>\n"
282 " check_swap (-V|--version)\n" " check_swap (-h|--help)\n");
283 }
289 void
290 print_help (void)
291 {
292 print_revision (PROGNAME, "$Revision$");
293 printf
294 ("Copyright (c) 2000 Karl DeBisschop\n\n"
295 "This plugin will check all of the swap partitions and return an\n"
296 "error if the the avalable swap space is less than specified.\n\n");
297 print_usage ();
298 printf
299 ("\nOptions:\n"
300 " -w, --warning=INTEGER\n"
301 " Exit with WARNING status if less than INTEGER bytes of swap space are free\n"
302 " -w, --warning=PERCENT%%\n"
303 " Exit with WARNING status if more than PERCENT of swap space has been used\n"
304 " -c, --critical=INTEGER\n"
305 " Exit with CRITICAL status if less than INTEGER bytes of swap space are free\n"
306 " -c, --critical=PERCENT%%\n"
307 " Exit with CRITCAL status if more than PERCENT of swap space has been used\n"
308 " -h, --help\n"
309 " Print detailed help screen\n"
310 " -V, --version\n" " Print version information\n\n");
311 support ();
312 }