Code

test total swap instead of individual disks
[nagiosplug.git] / plugins / check_swap.c
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;
151 /* process command-line arguments */
152 int
153 process_arguments (int argc, char **argv)
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 ();
256 int
257 validate_arguments (void)
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;
278 void
279 print_usage (void)
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");
291 void
292 print_help (void)
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 ();