check_swap.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  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;
  133. if (argc < 2)
  134. return ERROR;
  135. c = 0;
  136. while (c += (call_getopt (argc - c, &argv[c]))) {
  137. if (argc <= c)
  138. break;
  139. if (warn_percent > 100 && is_intnonneg (argv[c]))
  140. warn_percent = atoi (argv[c]);
  141. else if (crit_percent > 100 && is_intnonneg (argv[c]))
  142. crit_percent = atoi (argv[c]);
  143. else if (warn_size < 0 && is_intnonneg (argv[c]))
  144. warn_size = atoi (argv[c]);
  145. else if (crit_size < 0 && is_intnonneg (argv[c]))
  146. crit_size = atoi (argv[c]);
  147. }
  148. return validate_arguments ();
  149. }
  150. int
  151. call_getopt (int argc, char **argv)
  152. {
  153. int c, i = 0;
  154. #ifdef HAVE_GETOPT_H
  155. int option_index = 0;
  156. static struct option long_options[] = {
  157. {"warning", required_argument, 0, 'w'},
  158. {"critical", required_argument, 0, 'c'},
  159. {"verbose", no_argument, 0, 'v'},
  160. {"version", no_argument, 0, 'V'},
  161. {"help", no_argument, 0, 'h'},
  162. {0, 0, 0, 0}
  163. };
  164. #endif
  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
  171. i++;
  172. if (c == -1 || c == EOF)
  173. break;
  174. switch (c) {
  175. case 'c':
  176. case 'w':
  177. i++;
  178. }
  179. switch (c) {
  180. case 'w': /* warning time threshold */
  181. if (is_intnonneg (optarg)) {
  182. warn_size = atoi (optarg);
  183. break;
  184. }
  185. else if (strstr (optarg, ",") &&
  186. strstr (optarg, "%") &&
  187. sscanf (optarg, "%d,%d%%", &warn_size, &warn_percent) == 2) {
  188. break;
  189. }
  190. else if (strstr (optarg, "%") &&
  191. sscanf (optarg, "%d%%", &warn_percent) == 1) {
  192. break;
  193. }
  194. else {
  195. usage ("Warning threshold must be integer or percentage!\n");
  196. }
  197. case 'c': /* critical time threshold */
  198. if (is_intnonneg (optarg)) {
  199. crit_size = atoi (optarg);
  200. break;
  201. }
  202. else if (strstr (optarg, ",") &&
  203. strstr (optarg, "%") &&
  204. sscanf (optarg, "%d,%d%%", &crit_size, &crit_percent) == 2) {
  205. break;
  206. }
  207. else if (strstr (optarg, "%") &&
  208. sscanf (optarg, "%d%%", &crit_percent) == 1) {
  209. break;
  210. }
  211. else {
  212. usage ("Critical threshold must be integer or percentage!\n");
  213. }
  214. case 'V': /* version */
  215. print_revision (my_basename (argv[0]), "$Revision$");
  216. exit (STATE_OK);
  217. case 'h': /* help */
  218. print_help ();
  219. exit (STATE_OK);
  220. case '?': /* help */
  221. usage ("Invalid argument\n");
  222. }
  223. }
  224. return i;
  225. }
  226. int
  227. validate_arguments (void)
  228. {
  229. if (warn_percent > 100 && crit_percent > 100 && warn_size < 0
  230. && crit_size < 0) {
  231. return ERROR;
  232. }
  233. else if (warn_percent > crit_percent) {
  234. usage
  235. ("Warning percentage should not be less than critical percentage\n");
  236. }
  237. else if (warn_size < crit_size) {
  238. usage
  239. ("Warning free space should not be more than critical free space\n");
  240. }
  241. return OK;
  242. }
  243. void
  244. print_usage (void)
  245. {
  246. printf
  247. ("Usage: check_swap -w <used_percentage>%% -c <used_percentage>%%\n"
  248. " check_swap -w <bytes_free> -c <bytes_free>\n"
  249. " check_swap (-V|--version)\n" " check_swap (-h|--help)\n");
  250. }
  251. void
  252. print_help (void)
  253. {
  254. print_revision (PROGNAME, "$Revision$");
  255. printf
  256. ("Copyright (c) 2000 Karl DeBisschop\n\n"
  257. "This plugin will check all of the swap partitions and return an\n"
  258. "error if the the avalable swap space is less than specified.\n\n");
  259. print_usage ();
  260. printf
  261. ("\nOptions:\n"
  262. " -w, --warning=INTEGER\n"
  263. " Exit with WARNING status if less than INTEGER bytes of swap space are free\n"
  264. " -w, --warning=PERCENT%%\n"
  265. " Exit with WARNING status if more than PERCENT of swap space has been used\n"
  266. " -c, --critical=INTEGER\n"
  267. " Exit with CRITICAL status if less than INTEGER bytes of swap space are free\n"
  268. " -c, --critical=PERCENT%%\n"
  269. " Exit with CRITCAL status if more than PERCENT of swap space has been used\n"
  270. " -h, --help\n"
  271. " Print detailed help screen\n"
  272. " -V, --version\n" " Print version information\n\n");
  273. support ();
  274. }