From d47be7a9e48242a25e356e2509f6fb774ae0be10 Mon Sep 17 00:00:00 2001
From: Ton Voon <tonvoon@users.sourceforge.net>
Date: Wed, 25 Apr 2007 22:10:13 +0000
Subject: check_load can optionally divide by number of cpus

git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@1700 f882894a-f735-0410-b71e-b25c423dba1c

diff --git a/NEWS b/NEWS
index 863d1a6..eb84e0f 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,7 @@ This file documents the major additions and syntax changes between releases.
 	New/improved -E/--skip-stderr and -S/--skip-stdout options for check_by_ssh
 	check_snmp now support Counter64
 	Fix compilation of check_ldap, check_radius and check_pgsql
+	check_load can optionally divide by number of cpus
 
 1.4.8 11th April 2007
 	Respects --without-world-permissions for setuid plugins
diff --git a/configure.in b/configure.in
index 54040ac..891922e 100644
--- a/configure.in
+++ b/configure.in
@@ -1054,6 +1054,14 @@ if test -n "$ac_cv_nslookup_command"; then
 	AC_DEFINE_UNQUOTED(NSLOOKUP_COMMAND,"$ac_cv_nslookup_command", [path and args for nslookup])
 fi
 
+AC_MSG_CHECKING([for number of cpus])
+AC_TRY_COMPILE([#include <unistd.h>],
+	[sysconf(_SC_NPROCESSORS_CONF) > 0;],
+	AC_DEFINE(HAVE_SYSCONF__SC_NPROCESSORS_CONF,1,[Define if sysconf returns number of cpus])
+	AC_MSG_RESULT([sysconf(_SC_NPROCESSORS_CONF)]),
+	AC_MSG_RESULT([cannot calculate])
+	)
+
 AC_PATH_PROG(PATH_TO_UPTIME,uptime)
 AC_ARG_WITH(uptime_command,
             ACX_HELP_STRING([--with-uptime-command=PATH],
diff --git a/plugins/check_load.c b/plugins/check_load.c
index 3d00432..9de8ff7 100644
--- a/plugins/check_load.c
+++ b/plugins/check_load.c
@@ -71,6 +71,7 @@ double cload[3] = { 0.0, 0.0, 0.0 };
 #define la15 la[2]
 
 char *status_line;
+int take_into_account_cpus = 0;
 
 static void
 get_threshold(char *arg, double *th)
@@ -103,6 +104,7 @@ main (int argc, char **argv)
 {
 	int result;
 	int i;
+	long numcpus;
 
 	double la[3] = { 0.0, 0.0, 0.0 };	/* NetBSD complains about unitialized arrays */
 #ifndef HAVE_GETLOADAVG
@@ -163,6 +165,13 @@ main (int argc, char **argv)
 # endif
 #endif
 
+	if (take_into_account_cpus == 1) {
+		if ((numcpus = GET_NUMBER_OF_CPUS()) > 0) {
+			la[0] = la[0] / numcpus;
+			la[1] = la[1] / numcpus;
+			la[2] = la[2] / numcpus;
+		}
+	}
 	if ((la[0] < 0.0) || (la[1] < 0.0) || (la[2] < 0.0)) {
 #ifdef HAVE_GETLOADAVG
 		printf (_("Error in getloadavg()\n"));
@@ -208,6 +217,7 @@ process_arguments (int argc, char **argv)
 	static struct option longopts[] = {
 		{"warning", required_argument, 0, 'w'},
 		{"critical", required_argument, 0, 'c'},
+		{"percpu", no_argument, 0, 'r'},
 		{"version", no_argument, 0, 'V'},
 		{"help", no_argument, 0, 'h'},
 		{0, 0, 0, 0}
@@ -217,7 +227,7 @@ process_arguments (int argc, char **argv)
 		return ERROR;
 
 	while (1) {
-		c = getopt_long (argc, argv, "Vhc:w:", longopts, &option);
+		c = getopt_long (argc, argv, "Vhrc:w:", longopts, &option);
 
 		if (c == -1 || c == EOF)
 			break;
@@ -229,6 +239,9 @@ process_arguments (int argc, char **argv)
 		case 'c': /* critical time threshold */
 			get_threshold(optarg, cload);
 			break;
+		case 'r': /* Divide load average by number of CPUs */
+			take_into_account_cpus = 1;
+			break;
 		case 'V':									/* version */
 			print_revision (progname, revision);
 			exit (STATE_OK);
@@ -301,6 +314,8 @@ print_help (void)
   printf (" %s\n", "-c, --critical=CLOAD1,CLOAD5,CLOAD15");
   printf ("    %s\n", _("Exit with CRITICAL status if load average exceed CLOADn"));
   printf ("    %s\n", _("the load average format is the same used by \"uptime\" and \"w\""));
+  printf (" %s\n", "-r, --percpu");
+  printf ("    %s\n", _("Divide the load averages by the number of CPUs (when possible)"));
 
 	printf (_(UT_SUPPORT));
 }
@@ -309,5 +324,5 @@ void
 print_usage (void)
 {
   printf (_("Usage:"));
-	printf ("%s -w WLOAD1,WLOAD5,WLOAD15 -c CLOAD1,CLOAD5,CLOAD15\n", progname);
+	printf ("%s [-r] -w WLOAD1,WLOAD5,WLOAD15 -c CLOAD1,CLOAD5,CLOAD15\n", progname);
 }
diff --git a/plugins/common.h b/plugins/common.h
index dd9a056..752e21f 100644
--- a/plugins/common.h
+++ b/plugins/common.h
@@ -80,6 +80,18 @@
 #include <unistd.h>
 #endif
 
+/* GET_NUMBER_OF_CPUS is a macro to return 
+   number of CPUs, if we can get that data.
+   Use configure.in to test for various OS ways of
+   getting that data
+   Will return -1 if cannot get data
+*/
+#ifdef HAVE_SYSCONF__SC_NPROCESSORS_CONF 
+#define GET_NUMBER_OF_CPUS() sysconf(_SC_NPROCESSORS_CONF)
+#else
+#define GET_NUMBER_OF_CPUS() -1
+#endif
+
 #ifdef TIME_WITH_SYS_TIME
 # include <sys/time.h>
 # include <time.h>
diff --git a/plugins/t/check_load.t b/plugins/t/check_load.t
index 0804ac6..da87d16 100644
--- a/plugins/t/check_load.t
+++ b/plugins/t/check_load.t
@@ -14,7 +14,7 @@ my $res;
 my $successOutput = '/^OK - load average: [0-9]+\.?[0-9]+, [0-9]+\.?[0-9]+, [0-9]+\.?[0-9]+/';
 my $failureOutput = '/^CRITICAL - load average: [0-9]+\.?[0-9]+, [0-9]+\.?[0-9]+, [0-9]+\.?[0-9]+/';
 
-plan tests => 4;
+plan tests => 6;
 
 $res = NPTest->testCmd( "./check_load -w 100,100,100 -c 100,100,100" );
 cmp_ok( $res->return_code, 'eq', 0, "load not over 100");
@@ -24,3 +24,7 @@ $res = NPTest->testCmd( "./check_load -w 0,0,0 -c 0,0,0" );
 cmp_ok( $res->return_code, 'eq', 2, "Load over 0");
 like( $res->output, $failureOutput, "Output OK");
 
+$res = NPTest->testCmd( "./check_load -r -w 0,0,0 -c 0,0,0" );
+cmp_ok( $res->return_code, 'eq', 2, "Load over 0 with per cpu division");
+like( $res->output, $failureOutput, "Output OK");
+
-- 
cgit v0.10-9-g596f

