8e0a58985517d11a69b8b66bdfdd6bd268d54d21
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, used_swap, free_swap, percent_used;
30 int result = STATE_OK;
31 char input_buffer[MAX_INPUT_BUFFER];
32 #ifdef HAVE_SWAP
33 char *temp_buffer;
34 #endif
35 #ifdef HAVE_PROC_MEMINFO
36 FILE *fp;
37 #endif
38 char str[32];
39 char *status = NULL;
41 if (process_arguments (argc, argv) != OK)
42 usage ("Invalid command arguments supplied\n");
44 #ifdef HAVE_PROC_MEMINFO
45 fp = fopen (PROC_MEMINFO, "r");
46 asprintf (&status, "%s", "Swap used:");
47 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
48 sscanf (input_buffer, " %s %d %d %d", str, &total_swap, &used_swap,
49 &free_swap);
50 if (strstr (str, "Swap")) {
51 percent_used = 100 * (((float) used_swap) / ((float) total_swap));
52 asprintf (&status, "%s %2d%% (%d bytes out of %d)",
53 status, percent_used, used_swap, total_swap);
54 if (percent_used >= crit_percent || free_swap <= crit_size)
55 result = STATE_CRITICAL;
56 else if (percent_used >= warn_percent || free_swap <= warn_size)
57 result = STATE_WARNING;
58 break;
59 }
60 }
61 fclose (fp);
62 #else
63 #ifdef HAVE_SWAP
64 child_process = spopen (SWAP_COMMAND);
65 if (child_process == NULL) {
66 printf ("Could not open pipe: %s\n", SWAP_COMMAND);
67 return STATE_UNKNOWN;
68 }
70 child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
71 if (child_stderr == NULL)
72 printf ("Could not open stderr for %s\n", SWAP_COMMAND);
74 sprintf (str, "%s", "");
75 /* read 1st line */
76 fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process);
77 if (strcmp (SWAP_FORMAT, "") == 0) {
78 temp_buffer = strtok (input_buffer, " \n");
79 while (temp_buffer) {
80 if (strstr (temp_buffer, "blocks"))
81 sprintf (str, "%s %s", str, "%f");
82 else if (strstr (temp_buffer, "free"))
83 sprintf (str, "%s %s", str, "%f");
84 else
85 sprintf (str, "%s %s", str, "%*s");
86 temp_buffer = strtok (NULL, " \n");
87 }
88 }
90 asprintf (&status, "%s", "Swap used:");
91 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
92 sscanf (input_buffer, SWAP_FORMAT, &total_swap, &free_swap);
93 used_swap = total_swap - free_swap;
94 percent_used = 100 * ((float) used_swap) / ((float) total_swap);
95 asprintf (&status, "%s %2d%% (%d bytes out of %d)",
96 status, percent_used, used_swap, total_swap);
97 if (percent_used >= crit_percent || free_swap <= crit_size)
98 result = STATE_CRITICAL;
99 else if (percent_used >= warn_percent || free_swap <= warn_size)
100 result = STATE_WARNING;
101 }
103 /* If we get anything on STDERR, at least set warning */
104 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr))
105 result = max (result, STATE_WARNING);
107 /* close stderr */
108 (void) fclose (child_stderr);
110 /* close the pipe */
111 if (spclose (child_process))
112 result = max (result, STATE_WARNING);
113 #endif
114 #endif
116 #ifndef SWAP_COMMAND
117 #ifndef SWAP_FILE
118 #ifndef HAVE_PROC_MEMINFO
119 return STATE_UNKNOWN;
120 #endif
121 #endif
122 #endif
124 if (result == STATE_OK)
125 printf ("Swap ok - %s\n", status);
126 else if (result == STATE_CRITICAL)
127 printf ("CRITICAL - %s\n", status);
128 else if (result == STATE_WARNING)
129 printf ("WARNING - %s\n", status);
130 else if (result == STATE_UNKNOWN)
131 printf ("Unable to read output\n");
132 else {
133 result = STATE_UNKNOWN;
134 printf ("UNKNOWN - %s\n", status);
135 }
137 return result;
138 }
144 /* process command-line arguments */
145 int
146 process_arguments (int argc, char **argv)
147 {
148 int c, i = 0;
150 #ifdef HAVE_GETOPT_H
151 int option_index = 0;
152 static struct option long_options[] = {
153 {"warning", required_argument, 0, 'w'},
154 {"critical", required_argument, 0, 'c'},
155 {"verbose", no_argument, 0, 'v'},
156 {"version", no_argument, 0, 'V'},
157 {"help", no_argument, 0, 'h'},
158 {0, 0, 0, 0}
159 };
160 #endif
162 if (argc < 2)
163 return ERROR;
165 while (1) {
166 #ifdef HAVE_GETOPT_H
167 c = getopt_long (argc, argv, "+?Vhc:w:", long_options, &option_index);
168 #else
169 c = getopt (argc, argv, "+?Vhc:w:");
170 #endif
172 if (c == -1 || c == EOF)
173 break;
175 switch (c) {
176 case 'w': /* warning time threshold */
177 if (is_intnonneg (optarg)) {
178 warn_size = atoi (optarg);
179 break;
180 }
181 else if (strstr (optarg, ",") &&
182 strstr (optarg, "%") &&
183 sscanf (optarg, "%d,%d%%", &warn_size, &warn_percent) == 2) {
184 break;
185 }
186 else if (strstr (optarg, "%") &&
187 sscanf (optarg, "%d%%", &warn_percent) == 1) {
188 break;
189 }
190 else {
191 usage ("Warning threshold must be integer or percentage!\n");
192 }
193 case 'c': /* critical time threshold */
194 if (is_intnonneg (optarg)) {
195 crit_size = atoi (optarg);
196 break;
197 }
198 else if (strstr (optarg, ",") &&
199 strstr (optarg, "%") &&
200 sscanf (optarg, "%d,%d%%", &crit_size, &crit_percent) == 2) {
201 break;
202 }
203 else if (strstr (optarg, "%") &&
204 sscanf (optarg, "%d%%", &crit_percent) == 1) {
205 break;
206 }
207 else {
208 usage ("Critical threshold must be integer or percentage!\n");
209 }
210 case 'V': /* version */
211 print_revision (my_basename (argv[0]), "$Revision$");
212 exit (STATE_OK);
213 case 'h': /* help */
214 print_help ();
215 exit (STATE_OK);
216 case '?': /* help */
217 usage ("Invalid argument\n");
218 }
219 }
221 c = optind;
222 if (c == argc)
223 return validate_arguments ();
224 if (warn_percent > 100 && is_intnonneg (argv[c]))
225 warn_percent = atoi (argv[c++]);
227 if (c == argc)
228 return validate_arguments ();
229 if (crit_percent > 100 && is_intnonneg (argv[c]))
230 crit_percent = atoi (argv[c++]);
232 if (c == argc)
233 return validate_arguments ();
234 if (warn_size < 0 && is_intnonneg (argv[c]))
235 warn_size = atoi (argv[c++]);
237 if (c == argc)
238 return validate_arguments ();
239 if (crit_size < 0 && is_intnonneg (argv[c]))
240 crit_size = atoi (argv[c++]);
242 return validate_arguments ();
243 }
249 int
250 validate_arguments (void)
251 {
252 if (warn_percent > 100 && crit_percent > 100 && warn_size < 0
253 && crit_size < 0) {
254 return ERROR;
255 }
256 else if (warn_percent > crit_percent) {
257 usage
258 ("Warning percentage should not be less than critical percentage\n");
259 }
260 else if (warn_size < crit_size) {
261 usage
262 ("Warning free space should not be more than critical free space\n");
263 }
264 return OK;
265 }
271 void
272 print_usage (void)
273 {
274 printf
275 ("Usage: check_swap -w <used_percentage>%% -c <used_percentage>%%\n"
276 " check_swap -w <bytes_free> -c <bytes_free>\n"
277 " check_swap (-V|--version)\n" " check_swap (-h|--help)\n");
278 }
284 void
285 print_help (void)
286 {
287 print_revision (PROGNAME, "$Revision$");
288 printf
289 ("Copyright (c) 2000 Karl DeBisschop\n\n"
290 "This plugin will check all of the swap partitions and return an\n"
291 "error if the the avalable swap space is less than specified.\n\n");
292 print_usage ();
293 printf
294 ("\nOptions:\n"
295 " -w, --warning=INTEGER\n"
296 " Exit with WARNING status if less than INTEGER bytes of swap space are free\n"
297 " -w, --warning=PERCENT%%\n"
298 " Exit with WARNING status if more than PERCENT of swap space has been used\n"
299 " -c, --critical=INTEGER\n"
300 " Exit with CRITICAL status if less than INTEGER bytes of swap space are free\n"
301 " -c, --critical=PERCENT%%\n"
302 " Exit with CRITCAL status if more than PERCENT of swap space has been used\n"
303 " -h, --help\n"
304 " Print detailed help screen\n"
305 " -V, --version\n" " Print version information\n\n");
306 support ();
307 }