1--- docs/conf/extra/httpd-mpm.conf.in.orig 2010-10-28 15:17:47.000000000 -0500 2+++ docs/conf/extra/httpd-mpm.conf.in 2010-11-01 16:15:08.000000000 -0500 3@@ -33,11 +33,16 @@ 4 # MaxSpareServers: maximum number of server processes which are kept spare 5 # MaxClients: maximum number of server processes allowed to start 6 # MaxRequestsPerChild: maximum number of requests a server process serves 7+# ServerLimit and MaxClients support n% syntax which sets them to a 8+# fraction of the current RLIMIT_NPROC limit. On error the values 9+# are unchanged, so set a numeric value first just in case. 10 <IfModule mpm_prefork_module> 11 StartServers 1 12 MinSpareServers 1 13 MaxSpareServers 10 14+ ServerLimit 50% 15 MaxClients 150 16+ MaxClients 50% 17 MaxRequestsPerChild 0 18 </IfModule> 19 20--- server/mpm/prefork/prefork.c.orig 2010-10-11 23:21:28.000000000 -0500 21+++ server/mpm/prefork/prefork.c 2010-11-01 16:13:10.000000000 -0500 22@@ -1412,14 +1412,42 @@ 23 return NULL; 24 } 25 26+#include <sys/resource.h> 27+static int getproclimit(void) 28+{ 29+ struct rlimit rl; 30+ memset(&rl, 0, sizeof rl); 31+ return getrlimit(RLIMIT_NPROC, &rl) == 0 ? rl.rlim_cur : 0; 32+} 33+ 34 static const char *set_max_clients (cmd_parms *cmd, void *dummy, const char *arg) 35 { 36+ int tmp_daemons_limit; 37+ 38 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); 39 if (err != NULL) { 40 return err; 41 } 42 43- ap_daemons_limit = atoi(arg); 44+ tmp_daemons_limit = atoi(arg); 45+ if (strlen(arg) > 0 && arg[strlen(arg) - 1] == '%') { 46+ int proclimit = getproclimit(); 47+ if (proclimit <= 0) { 48+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 49+ "WARNING: MaxClients %d%% ignored because " 50+ "RLIMIT_NPROC is unknown", tmp_daemons_limit); 51+ return NULL; 52+ } 53+ if (tmp_daemons_limit < 1 || tmp_daemons_limit > 100) { 54+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 55+ "WARNING: MaxClients %d%% ignored because " 56+ "percentage is out of range 1-100%%", 57+ tmp_daemons_limit); 58+ return NULL; 59+ } 60+ tmp_daemons_limit = proclimit * tmp_daemons_limit / 100.0 + 0.5; 61+ } 62+ ap_daemons_limit = tmp_daemons_limit; 63 if (ap_daemons_limit > server_limit) { 64 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 65 "WARNING: MaxClients of %d exceeds ServerLimit value " 66@@ -1449,6 +1477,23 @@ 67 } 68 69 tmp_server_limit = atoi(arg); 70+ if (strlen(arg) > 0 && arg[strlen(arg) - 1] == '%') { 71+ int proclimit = getproclimit(); 72+ if (proclimit <= 0) { 73+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 74+ "WARNING: ServerLimit %d%% ignored because " 75+ "RLIMIT_NPROC is unknown", tmp_server_limit); 76+ return NULL; 77+ } 78+ if (tmp_server_limit < 1 || tmp_server_limit > 100) { 79+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, 80+ "WARNING: ServerLimit %d%% ignored because " 81+ "percentage is out of range 1-100%%", 82+ tmp_server_limit); 83+ return NULL; 84+ } 85+ tmp_server_limit = proclimit * tmp_server_limit / 100.0 + 0.5; 86+ } 87 /* you cannot change ServerLimit across a restart; ignore 88 * any such attempts 89 */ 90