check_swap.c 7.8 KB

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