From 0b36348b1281b855a8681cd6e4f747f3f7c3f2f4 Mon Sep 17 00:00:00 2001
From: Mark Spencer <markster@digium.com>
Date: Wed, 26 Oct 2005 03:58:32 +0000
Subject: [PATCH] Allow limitation by loadavg not just calls (should be BSD
 friendly)...

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@6850 65c4cc65-6c06-0410-ace0-fbb531ad65f3
---
 asterisk.8                 |  7 ++++++-
 asterisk.c                 | 11 ++++++++++-
 asterisk.sgml              | 10 ++++++++++
 include/asterisk/options.h |  1 +
 pbx.c                      |  9 ++++++++-
 5 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/asterisk.8 b/asterisk.8
index 6831d0fa89..fe0a9ba863 100755
--- a/asterisk.8
+++ b/asterisk.8
@@ -3,7 +3,7 @@
 .\" <http://shell.ipoline.com/~elmert/comp/docbook2X/> 
 .\" Please send any bug reports, improvements, comments, patches, 
 .\" etc. to Steve Cheng <steve@ggi-project.org>.
-.TH "ASTERISK" "8" "18 October 2005" "asterisk 1.2" ""
+.TH "ASTERISK" "8" "25 October 2005" "asterisk 1.2" ""
 
 .SH NAME
 asterisk \- All-purpose telephony server.
@@ -80,6 +80,11 @@ Provide brief summary of command line arguments and terminate.
 Prompt user to intialize any encrypted private keys for IAX2
 secure authentication during startup.
 .TP
+\fB-L \fIloadaverage\fB\fR
+Limits the maximum load average before rejecting new calls.  This can
+be useful to prevent a system from being brought down by terminating
+too many simultaneous calls.
+.TP
 \fB-M \fIvalue\fB\fR
 Limits the maximum number of calls to the specified value.  This can
 be useful to prevent a system from being brought down by terminating
diff --git a/asterisk.c b/asterisk.c
index 4c3bef8dcb..1596959ed5 100755
--- a/asterisk.c
+++ b/asterisk.c
@@ -143,6 +143,7 @@ int option_overrideconfig = 0;
 int option_reconnect = 0;
 int option_transcode_slin = 1;
 int option_maxcalls = 0;
+double option_maxload = 0.0;
 int option_dontwarn = 0;
 int option_priority_jumping = 1;
 int fully_booted = 0;
@@ -1872,6 +1873,10 @@ static void ast_readconfig(void) {
 			if ((sscanf(v->value, "%d", &option_maxcalls) != 1) || (option_maxcalls < 0)) {
 				option_maxcalls = 0;
 			}
+		} else if (!strcasecmp(v->name, "maxload")) {
+			if ((sscanf(v->value, "%lf", &option_maxload) != 1) || (option_maxload < 0.0)) {
+				option_maxload = 0.0;
+			}
 		}
 		v = v->next;
 	}
@@ -1930,7 +1935,7 @@ int main(int argc, char *argv[])
 	}
 	*/
 	/* Check for options */
-	while((c=getopt(argc, argv, "tThfdvVqprRgcinx:U:G:C:M:")) != -1) {
+	while((c=getopt(argc, argv, "tThfdvVqprRgcinx:U:G:C:L:M:")) != -1) {
 		switch(c) {
 		case 'd':
 			option_debug++;
@@ -1966,6 +1971,10 @@ int main(int argc, char *argv[])
 			if ((sscanf(optarg, "%d", &option_maxcalls) != 1) || (option_maxcalls < 0))
 				option_maxcalls = 0;
 			break;
+		case 'L':
+			if ((sscanf(optarg, "%lf", &option_maxload) != 1) || (option_maxload < 0.0))
+				option_maxload = 0.0;
+			break;
 		case 'q':
 			option_quiet++;
 			break;
diff --git a/asterisk.sgml b/asterisk.sgml
index c29b4af304..60d399d1ba 100755
--- a/asterisk.sgml
+++ b/asterisk.sgml
@@ -152,6 +152,16 @@
 			</para>
 		</listitem>
 	</varlistentry>
+	<varlistentry>
+		<term>-L <replaceable class="parameter">loadaverage</replaceable></term>
+		<listitem>
+			<para>
+			Limits the maximum load average before rejecting new calls.  This can
+			be useful to prevent a system from being brought down by terminating
+			too many simultaneous calls.
+			</para>
+		</listitem>
+	</varlistentry>
 	<varlistentry>
 		<term>-M <replaceable class="parameter">value</replaceable></term>
 		<listitem>
diff --git a/include/asterisk/options.h b/include/asterisk/options.h
index 20df377fb2..52f0af0271 100755
--- a/include/asterisk/options.h
+++ b/include/asterisk/options.h
@@ -43,6 +43,7 @@ extern int option_cache_record_files;
 extern int option_timestamp;
 extern int option_transcode_slin;
 extern int option_maxcalls;
+extern double option_maxload;
 extern int option_dontwarn;
 extern int option_priority_jumping;
 extern char defaultlanguage[];
diff --git a/pbx.c b/pbx.c
index b629980b01..843ce1daa7 100755
--- a/pbx.c
+++ b/pbx.c
@@ -2477,7 +2477,7 @@ out:
 static int increase_call_count(const struct ast_channel *c)
 {
 	int failed = 0;
-
+	double curloadavg;
 	ast_mutex_lock(&maxcalllock);
 	if (option_maxcalls) {
 		if (countcalls >= option_maxcalls) {
@@ -2485,6 +2485,13 @@ static int increase_call_count(const struct ast_channel *c)
 			failed = -1;
 		}
 	}
+	if (option_maxload) {
+		getloadavg(&curloadavg, 1);
+		if (curloadavg >= option_maxload) {
+			ast_log(LOG_NOTICE, "Maximum loadavg limit of %lf load exceeded by '%s' (currently %f)!\n", option_maxload, c->name, curloadavg);
+			failed = -1;
+		}
+	}
 	if (!failed)
 		countcalls++;	
 	ast_mutex_unlock(&maxcalllock);
-- 
GitLab