check_swap.c 7.7 KB

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