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 validate_arguments (void);
21 void print_usage (void);
22 void print_help (void);
24 int warn_percent = 200, crit_percent = 200, warn_size = -1, crit_size = -1;
26 int
27 main (int argc, char **argv)
28 {
29 int total_swap = 0, used_swap = 0, free_swap = 0, percent_used;
30 int total, used, free;
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 = "";
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 asprintf (&status, "%s", "Swap used:");
48 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
49 if (sscanf (input_buffer, " %s %d %d %d", str, &total, &used, &free) == 4 &&
50 strstr (str, "Swap")) {
51 /* asprintf (&status, "%s [%d/%d]", status, used, total); */
52 total_swap += total;
53 used_swap += used;
54 free_swap += free;
55 }
56 }
57 percent_used = 100 * (((float) used_swap) / ((float) total_swap));
58 if (percent_used >= crit_percent || free_swap <= crit_size)
59 result = STATE_CRITICAL;
60 else if (percent_used >= warn_percent || free_swap <= warn_size)
61 result = STATE_WARNING;
62 asprintf (&status, "%s %2d%% (%d out of %d)", status, percent_used,
63 used_swap, total_swap);
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 asprintf (&status, "%s", "Swap used:");
94 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
95 sscanf (input_buffer, SWAP_FORMAT, &total, &free);
96 used = total - free;
97 /* asprintf (&status, "%s [%d/%d]", status, used, total); */
98 total_swap += total;
99 used_swap += used;
100 free_swap += free;
101 }
102 percent_used = 100 * ((float) used_swap) / ((float) total_swap);
103 asprintf (&status, "%s %2d%% (%d out of %d)",
104 status, percent_used, used_swap, total_swap);
105 if (percent_used >= crit_percent || free_swap <= crit_size)
106 result = STATE_CRITICAL;
107 else if (percent_used >= warn_percent || free_swap <= warn_size)
108 result = STATE_WARNING;
110 /* If we get anything on STDERR, at least set warning */
111 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr))
112 result = max (result, STATE_WARNING);
114 /* close stderr */
115 (void) fclose (child_stderr);
117 /* close the pipe */
118 if (spclose (child_process))
119 result = max (result, STATE_WARNING);
120 #endif
121 #endif
123 #ifndef SWAP_COMMAND
124 #ifndef SWAP_FILE
125 #ifndef HAVE_PROC_MEMINFO
126 return STATE_UNKNOWN;
127 #endif
128 #endif
129 #endif
131 if (result == STATE_OK)
132 printf ("Swap ok - %s\n", status);
133 else if (result == STATE_CRITICAL)
134 printf ("CRITICAL - %s\n", status);
135 else if (result == STATE_WARNING)
136 printf ("WARNING - %s\n", status);
137 else if (result == STATE_UNKNOWN)
138 printf ("Unable to read output\n");
139 else {
140 result = STATE_UNKNOWN;
141 printf ("UNKNOWN - %s\n", status);
142 }
144 return result;
145 }
151 /* process command-line arguments */
152 int
153 process_arguments (int argc, char **argv)
154 {
155 int c, i = 0;
157 #ifdef HAVE_GETOPT_H
158 int option_index = 0;
159 static struct option long_options[] = {
160 {"warning", required_argument, 0, 'w'},
161 {"critical", required_argument, 0, 'c'},
162 {"verbose", no_argument, 0, 'v'},
163 {"version", no_argument, 0, 'V'},
164 {"help", no_argument, 0, 'h'},
165 {0, 0, 0, 0}
166 };
167 #endif
169 if (argc < 2)
170 return ERROR;
172 while (1) {
173 #ifdef HAVE_GETOPT_H
174 c = getopt_long (argc, argv, "+?Vhc:w:", long_options, &option_index);
175 #else
176 c = getopt (argc, argv, "+?Vhc:w:");
177 #endif
179 if (c == -1 || c == EOF)
180 break;
182 switch (c) {
183 case 'w': /* warning time threshold */
184 if (is_intnonneg (optarg)) {
185 warn_size = atoi (optarg);
186 break;
187 }
188 else if (strstr (optarg, ",") &&
189 strstr (optarg, "%") &&
190 sscanf (optarg, "%d,%d%%", &warn_size, &warn_percent) == 2) {
191 break;
192 }
193 else if (strstr (optarg, "%") &&
194 sscanf (optarg, "%d%%", &warn_percent) == 1) {
195 break;
196 }
197 else {
198 usage ("Warning threshold must be integer or percentage!\n");
199 }
200 case 'c': /* critical time threshold */
201 if (is_intnonneg (optarg)) {
202 crit_size = atoi (optarg);
203 break;
204 }
205 else if (strstr (optarg, ",") &&
206 strstr (optarg, "%") &&
207 sscanf (optarg, "%d,%d%%", &crit_size, &crit_percent) == 2) {
208 break;
209 }
210 else if (strstr (optarg, "%") &&
211 sscanf (optarg, "%d%%", &crit_percent) == 1) {
212 break;
213 }
214 else {
215 usage ("Critical threshold must be integer or percentage!\n");
216 }
217 case 'V': /* version */
218 print_revision (my_basename (argv[0]), "$Revision$");
219 exit (STATE_OK);
220 case 'h': /* help */
221 print_help ();
222 exit (STATE_OK);
223 case '?': /* help */
224 usage ("Invalid argument\n");
225 }
226 }
228 c = optind;
229 if (c == argc)
230 return validate_arguments ();
231 if (warn_percent > 100 && is_intnonneg (argv[c]))
232 warn_percent = atoi (argv[c++]);
234 if (c == argc)
235 return validate_arguments ();
236 if (crit_percent > 100 && is_intnonneg (argv[c]))
237 crit_percent = atoi (argv[c++]);
239 if (c == argc)
240 return validate_arguments ();
241 if (warn_size < 0 && is_intnonneg (argv[c]))
242 warn_size = atoi (argv[c++]);
244 if (c == argc)
245 return validate_arguments ();
246 if (crit_size < 0 && is_intnonneg (argv[c]))
247 crit_size = atoi (argv[c++]);
249 return validate_arguments ();
250 }
256 int
257 validate_arguments (void)
258 {
259 if (warn_percent > 100 && crit_percent > 100 && warn_size < 0
260 && crit_size < 0) {
261 return ERROR;
262 }
263 else if (warn_percent > crit_percent) {
264 usage
265 ("Warning percentage should not be less than critical percentage\n");
266 }
267 else if (warn_size < crit_size) {
268 usage
269 ("Warning free space should not be more than critical free space\n");
270 }
271 return OK;
272 }
278 void
279 print_usage (void)
280 {
281 printf
282 ("Usage: check_swap -w <used_percentage>%% -c <used_percentage>%%\n"
283 " check_swap -w <bytes_free> -c <bytes_free>\n"
284 " check_swap (-V|--version)\n" " check_swap (-h|--help)\n");
285 }
291 void
292 print_help (void)
293 {
294 print_revision (PROGNAME, "$Revision$");
295 printf
296 ("Copyright (c) 2000 Karl DeBisschop\n\n"
297 "This plugin will check all of the swap partitions and return an\n"
298 "error if the the avalable swap space is less than specified.\n\n");
299 print_usage ();
300 printf
301 ("\nOptions:\n"
302 " -w, --warning=INTEGER\n"
303 " Exit with WARNING status if less than INTEGER bytes of swap space are free\n"
304 " -w, --warning=PERCENT%%\n"
305 " Exit with WARNING status if more than PERCENT of swap space has been used\n"
306 " -c, --critical=INTEGER\n"
307 " Exit with CRITICAL status if less than INTEGER bytes of swap space are free\n"
308 " -c, --critical=PERCENT%%\n"
309 " Exit with CRITCAL status if more than PERCENT of swap space has been used\n"
310 " -h, --help\n"
311 " Print detailed help screen\n"
312 " -V, --version\n" " Print version information\n\n");
313 support ();
314 }