check_swap.c 7.6 KB

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