PR-6223104-ulimit.diff [plain text]
--- docs/conf/extra/httpd-mpm.conf.in.orig 2010-10-28 15:17:47.000000000 -0500
+++ docs/conf/extra/httpd-mpm.conf.in 2010-11-01 16:15:08.000000000 -0500
@@ -33,11 +33,16 @@
# MaxSpareServers: maximum number of server processes which are kept spare
# MaxClients: maximum number of server processes allowed to start
# MaxRequestsPerChild: maximum number of requests a server process serves
+# ServerLimit and MaxClients support n% syntax which sets them to a
+# fraction of the current RLIMIT_NPROC limit. On error the values
+# are unchanged, so set a numeric value first just in case.
<IfModule mpm_prefork_module>
StartServers 1
MinSpareServers 1
MaxSpareServers 10
+ ServerLimit 50%
MaxClients 150
+ MaxClients 50%
MaxRequestsPerChild 0
</IfModule>
--- server/mpm/prefork/prefork.c.orig 2010-10-11 23:21:28.000000000 -0500
+++ server/mpm/prefork/prefork.c 2010-11-01 16:13:10.000000000 -0500
@@ -1412,14 +1412,42 @@
return NULL;
}
+#include <sys/resource.h>
+static int getproclimit(void)
+{
+ struct rlimit rl;
+ memset(&rl, 0, sizeof rl);
+ return getrlimit(RLIMIT_NPROC, &rl) == 0 ? rl.rlim_cur : 0;
+}
+
static const char *set_max_clients (cmd_parms *cmd, void *dummy, const char *arg)
{
+ int tmp_daemons_limit;
+
const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
if (err != NULL) {
return err;
}
- ap_daemons_limit = atoi(arg);
+ tmp_daemons_limit = atoi(arg);
+ if (strlen(arg) > 0 && arg[strlen(arg) - 1] == '%') {
+ int proclimit = getproclimit();
+ if (proclimit <= 0) {
+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
+ "WARNING: MaxClients %d%% ignored because "
+ "RLIMIT_NPROC is unknown", tmp_daemons_limit);
+ return NULL;
+ }
+ if (tmp_daemons_limit < 1 || tmp_daemons_limit > 100) {
+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
+ "WARNING: MaxClients %d%% ignored because "
+ "percentage is out of range 1-100%%",
+ tmp_daemons_limit);
+ return NULL;
+ }
+ tmp_daemons_limit = proclimit * tmp_daemons_limit / 100.0 + 0.5;
+ }
+ ap_daemons_limit = tmp_daemons_limit;
if (ap_daemons_limit > server_limit) {
ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
"WARNING: MaxClients of %d exceeds ServerLimit value "
@@ -1449,6 +1477,23 @@
}
tmp_server_limit = atoi(arg);
+ if (strlen(arg) > 0 && arg[strlen(arg) - 1] == '%') {
+ int proclimit = getproclimit();
+ if (proclimit <= 0) {
+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
+ "WARNING: ServerLimit %d%% ignored because "
+ "RLIMIT_NPROC is unknown", tmp_server_limit);
+ return NULL;
+ }
+ if (tmp_server_limit < 1 || tmp_server_limit > 100) {
+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
+ "WARNING: ServerLimit %d%% ignored because "
+ "percentage is out of range 1-100%%",
+ tmp_server_limit);
+ return NULL;
+ }
+ tmp_server_limit = proclimit * tmp_server_limit / 100.0 + 0.5;
+ }
/* you cannot change ServerLimit across a restart; ignore
* any such attempts
*/