[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[patch] teaching httpd to rlimit its child processes



This patch adds some new directives to httpd to rlimit the child httpd
processes. I've been running this on a webmail cluster that was
getting the crap kicked out of it by horde/imp, specifically by what
appeared to be memory leaks in php.

We've been running this for about 4 months and it's been quite useful.

Index: conf/highperformance.conf-dist
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/conf/highperformance.conf-dist,v
retrieving revision 1.4
diff -u -r1.4 highperformance.conf-dist
--- conf/highperformance.conf-dist      2002/02/12 07:56:46     1.4
+++ conf/highperformance.conf-dist      2005/11/22 20:44:21
@@ -21,6 +21,13 @@
 # Assume no memory leaks at all
 MaxRequestsPerChild 0

+# Wide-open rlimits.
+MaxCPUPerChild 0
+MaxDATAPerChild 0
+MaxNOFILEPerChild 0
+MaxRSSPerChild 0
+MaxSTACKPerChild 0
+
 # this is a True Config File
 # see http://www.apache.org/info/three-config-files.html
 ResourceConfig /dev/null
Index: conf/httpd.conf
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/conf/httpd.conf,v
retrieving revision 1.18
diff -u -r1.18 httpd.conf
--- conf/httpd.conf     2004/09/10 03:19:03     1.18
+++ conf/httpd.conf     2005/11/22 20:44:21
@@ -161,6 +161,17 @@
 MaxRequestsPerChild 0

 #
+# MaxFOOPerChild: these directives set the current and hard rlimits for
+# the child processes. Attempts to exceed them will cause the the OS to
+# take appropriate action. See the setrlimit(2) and signal(3).
+#
+MaxCPUPerChild 0
+MaxDATAPerChild 0
+MaxNOFILEPerChild 0
+MaxRSSPerChild 0
+MaxSTACKPerChild 0
+
+#
 # Listen: Allows you to bind Apache to specific IP addresses and/or
 # ports, in addition to the default. See also the <VirtualHost>
 # directive.
Index: conf/httpd.conf-dist
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/conf/httpd.conf-dist,v
retrieving revision 1.16
diff -u -r1.16 httpd.conf-dist
--- conf/httpd.conf-dist        2003/11/17 18:57:04     1.16
+++ conf/httpd.conf-dist        2005/11/22 20:44:21
@@ -167,6 +167,17 @@
 MaxRequestsPerChild 0

 #
+# MaxFOOPerChild: these directives set the current and hard rlimits for
+# the child processes. Attempts to exceed them will cause the the OS to
+# take appropriate action. See the setrlimit(2) and signal(3).
+#
+MaxCPUPerChild 0
+MaxDATAPerChild 0
+MaxNOFILEPerChild 0
+MaxRSSPerChild 0
+MaxSTACKPerChild 0
+
+#
 # Listen: Allows you to bind Apache to specific IP addresses and/or
 # ports, instead of the default. See also the <VirtualHost>
 # directive.
Index: htdocs/manual/server-wide.html
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/htdocs/manual/server-wide.html,v
retrieving revision 1.1
diff -u -r1.1 server-wide.html
--- htdocs/manual/server-wide.html      2005/07/29 23:55:39     1.1
+++ htdocs/manual/server-wide.html      2005/11/22 20:44:21
@@ -116,6 +116,11 @@
          <a href="mod/core.html#maxclients">MaxClients</a><br />
          <a
         href="mod/core.html#maxrequestsperchild">MaxRequestsPerChild</a><br />
+         <a href="mod/core.html#maxfooperchild">MaxCPUPerChild</a><br />
+         <a href="mod/core.html#maxfooperchild">MaxDATAPerChild</a><br />
+         <a href="mod/core.html#maxfooperchild">MaxNOFILEPerChild</a><br />
+         <a href="mod/core.html#maxfooperchild">MaxRSSPerChild</a><br />
+         <a href="mod/core.html#maxfooperchild">MaxSTACKPerChild</a><br />
          <a
         href="mod/core.html#maxspareservers">MaxSpareServers</a><br />
          <a
@@ -164,6 +169,10 @@
     possible. In addition, unless <a href="suexec.html">suexec</a>
     is used, these directives also set the privileges which will be
     inherited by CGI scripts.</p>
+
+    <p><a href="mod/core.html#maxfooperchild"><code>MaxFOOPerChild</code></a>
+    sets rlimits on a child process to prevent a leaky module from
+    taking down the whole server.</p>

     <p><code>MaxRequestsPerChild</code> controls how frequently the
     server recycles processes by killing old ones and launching new
Index: htdocs/manual/misc/perf-tuning.html
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/htdocs/manual/misc/perf-tuning.html,v
retrieving revision 1.8
diff -u -r1.8 perf-tuning.html
--- htdocs/manual/misc/perf-tuning.html 2003/08/21 13:11:32     1.8
+++ htdocs/manual/misc/perf-tuning.html 2005/11/22 20:44:21
@@ -321,6 +321,15 @@
     href="http://www.research.compaq.com/wrl/techreports/abstracts/95.4.html";>
     most of the benefits are lost</a>.</p>

+    <p>Related to process creation is process death induced by the <a
+    href="../mod/core.html#maxfooperchild"><code>MaxFOOPerChild</code></a>
+    setting, where FOO is one of the system resource limits. There are
+    directives to control the CPU, DATA, NOFILE, RSS and STACK rlimits.
+    By default, they are set to 0, meaning that the system default values
+    will be used for the child. On a busy server with script interpreters
+    and memory caches, these should be set to some appropriate finite
+    values.</p>
+
     <h4><a name="modules" id="modules">Modules</a></h4>

     <p>Since memory usage is such an important consideration in
Index: htdocs/manual/mod/core.html
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/htdocs/manual/mod/core.html,v
retrieving revision 1.10
diff -u -r1.10 core.html
--- htdocs/manual/mod/core.html 2005/07/29 23:55:39     1.10
+++ htdocs/manual/mod/core.html 2005/11/22 20:44:21
@@ -134,6 +134,12 @@
       <li><a
       href="#maxrequestsperchild">MaxRequestsPerChild</a></li>

+      <li><a href="#maxfooperchild">MaxCPUPerChild</a></li>
+      <li><a href="#maxfooperchild">MaxDATAPerChild</a></li>
+      <li><a href="#maxfooperchild">MaxNOFILEPerChild</a></li>
+      <li><a href="#maxfooperchild">MaxRSSPerChild</a></li>
+      <li><a href="#maxfooperchild">MaxSTACKPerChild</a></li>
+
       <li><a href="#maxspareservers">MaxSpareServers</a></li>

       <li><a href="#minspareservers">MinSpareServers</a></li>
@@ -2704,6 +2710,39 @@
     the first request is counted towards this limit. In effect, it
     changes the behavior to limit the number of
     <em>connections</em> per child.</p>
+    <hr />
+
+    <h2><a id="maxfooperchild"
+    name="maxfooperchild">MaxFOOPerChild directive</a></h2>
+
+    <a href="directive-dict.html#Syntax"
+    rel="Help"><strong>Syntax:</strong></a><br>
+    MaxCPUPerChild <em>number</em><br />
+    MaxDATAPerChild <em>number</em><br />
+    MaxNOFILEPerChild <em>number</em><br />
+    MaxRSSPerChild <em>number</em><br />
+    MaxSTACKPerChild <em>number</em><br />
+     <a href="directive-dict.html#Default"
+    rel="Help"><strong>Default:</strong></a>
+    <code>0 (no set limit)</code><br />
+     <a href="directive-dict.html#Context"
+    rel="Help"><strong>Context:</strong></a> server config<br />
+     <a href="directive-dict.html#Status"
+    rel="Help"><strong>Status:</strong></a> core
+
+    <p>The MaxFOOPerChild directives set the soft and hard resource
+    limits for a child process using setrlimit(2). Each MaxFOOPerChild
+    limit can be set independently of any other limit, or may be left
+    unspecified, thereby using the system default value. The kernel will
+    take appropriate action when a child process a resource limit - see
+    the manpages for setrlimit(2) and signal(3) for more information.
+    Setting resource limits can be very useful when running a busy server
+    with a script interpreter (say, a webmail machine) as these limits
+    can prevent swapping, deadlock or kernel panic due to memory or swap
+    exhaustion.</p>
+
+    <p>The name of the limit to be set is capitalized and spelled as
+    it is found in the setrlimit(2) manpage.</p>
     <hr />

     <h2><a id="maxspareservers"
Index: htdocs/manual/mod/directives.html
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/htdocs/manual/mod/directives.html,v
retrieving revision 1.10
diff -u -r1.10 directives.html
--- htdocs/manual/mod/directives.html   2005/08/01 19:40:33     1.10
+++ htdocs/manual/mod/directives.html   2005/11/22 20:44:21
@@ -368,6 +368,12 @@
       <li><a
       href="core.html#maxrequestsperchild">MaxRequestsPerChild</a></li>

+      <li><a href="core.html#maxfooperchild">MaxCPUPerChild</a></li>
+      <li><a href="core.html#maxfooperchild">MaxDATAPerChild</a></li>
+      <li><a href="core.html#maxfooperchild">MaxNOFILEPerChild</a></li>
+      <li><a href="core.html#maxfooperchild">MaxRSSPerChild</a></li>
+      <li><a href="core.html#maxfooperchild">MaxSTACKPerChild</a></li>
+
       <li><a
       href="core.html#maxspareservers">MaxSpareServers</a></li>

Index: htdocs/manual/vhosts/virtual-host.html
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/htdocs/manual/vhosts/virtual-host.html,v
retrieving revision 1.5
diff -u -r1.5 virtual-host.html
--- htdocs/manual/vhosts/virtual-host.html      2005/07/28 19:37:17     1.5
+++ htdocs/manual/vhosts/virtual-host.html      2005/11/22 20:44:21
@@ -153,6 +153,11 @@
     href="../mod/core.html#maxspareservers">MaxSpareServers</a>, <a
     href="../mod/core.html#minspareservers">MinSpareServers</a>, <a
     href="../mod/core.html#maxrequestsperchild">MaxRequestsPerChild</a>,
+    <a href="../mod/core.html#maxfooperchild">MaxCPUPerChild</a>,
+    <a href="../mod/core.html#maxfooperchild">MaxDATAPerChild</a>,
+    <a href="../mod/core.html#maxfooperchild">MaxNOFILEPerChild</a>,
+    <a href="../mod/core.html#maxfooperchild">MaxRSSPerChild</a>,
+    <a href="../mod/core.html#maxfooperchild">MaxSTACKPerChild</a>,
     <a href="../mod/core.html#bindaddress">BindAddress</a>, <a
     href="../mod/core.html#pidfile">PidFile</a>, <a
     href="../mod/mod_mime.html#typesconfig">TypesConfig</a>, and <a
Index: src/include/ap_compat.h
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/src/include/ap_compat.h,v
retrieving revision 1.4
diff -u -r1.4 ap_compat.h
--- src/include/ap_compat.h     2005/04/05 21:48:41     1.4
+++ src/include/ap_compat.h     2005/11/22 20:44:21
@@ -206,6 +206,11 @@
 #define make_table                     ap_make_table
 #define matches_request_vhost          ap_matches_request_vhost
 #define max_requests_per_child         ap_max_requests_per_child
+#define max_cpu_per_child              ap_max_cpu_per_child
+#define max_data_per_child             ap_max_data_per_child
+#define max_nofile_per_child           ap_max_nofile_per_child
+#define max_rss_per_child              ap_max_rss_per_child
+#define max_stack_per_child            ap_max_stack_per_child
 #define md5                            ap_md5
 #define meets_conditions               ap_meets_conditions
 #define merge_per_dir_configs          ap_merge_per_dir_configs
Index: src/include/http_conf_globals.h
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/src/include/http_conf_globals.h,v
retrieving revision 1.15
diff -u -r1.15 http_conf_globals.h
--- src/include/http_conf_globals.h     2005/03/28 23:26:51     1.15
+++ src/include/http_conf_globals.h     2005/11/22 20:44:21
@@ -76,6 +76,11 @@
 extern API_VAR_EXPORT char *ap_user_name;
 extern API_VAR_EXPORT gid_t ap_group_id;
 extern API_VAR_EXPORT int ap_max_requests_per_child;
+extern API_VAR_EXPORT int ap_max_cpu_per_child;
+extern API_VAR_EXPORT int ap_max_data_per_child;
+extern API_VAR_EXPORT int ap_max_nofile_per_child;
+extern API_VAR_EXPORT int ap_max_rss_per_child;
+extern API_VAR_EXPORT int ap_max_stack_per_child;
 extern API_VAR_EXPORT int ap_threads_per_child;
 extern API_VAR_EXPORT int ap_excess_requests_per_child;
 extern API_VAR_EXPORT struct in_addr ap_bind_address;
Index: src/include/httpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/src/include/httpd.h,v
retrieving revision 1.26
diff -u -r1.26 httpd.h
--- src/include/httpd.h 2005/06/15 00:00:16     1.26
+++ src/include/httpd.h 2005/11/22 20:44:21
@@ -354,6 +354,23 @@
 #define DEFAULT_EXCESS_REQUESTS_PER_CHILD 0
 #endif

+/* Constrain the rlimits of the child processes */
+#ifndef DEFAULT_MAX_CPU_PER_CHILD
+#define DEFAULT_MAX_CPU_PER_CHILD 0
+#endif
+#ifndef DEFAULT_MAX_DATA_PER_CHILD
+#define DEFAULT_MAX_DATA_PER_CHILD 0
+#endif
+#ifndef DEFAULT_MAX_NOFILE_PER_CHILD
+#define DEFAULT_MAX_NOFILE_PER_CHILD 0
+#endif
+#ifndef DEFAULT_MAX_RSS_PER_CHILD
+#define DEFAULT_MAX_RSS_PER_CHILD 0
+#endif
+#ifndef DEFAULT_MAX_STACK_PER_CHILD
+#define DEFAULT_MAX_STACK_PER_CHILD 0
+#endif
+
 /* The maximum length of the queue of pending connections, as defined
  * by listen(2).  Under some systems, it should be increased if you
  * are experiencing a heavy TCP SYN flood attack.
Index: src/main/http_config.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/src/main/http_config.c,v
retrieving revision 1.16
diff -u -r1.16 http_config.c
--- src/main/http_config.c      2005/02/09 12:13:09     1.16
+++ src/main/http_config.c      2005/11/22 20:44:21
@@ -1549,6 +1549,11 @@
     ap_scoreboard_fname = DEFAULT_SCOREBOARD;
     ap_lock_fname = DEFAULT_LOCKFILE;
     ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD;
+    ap_max_cpu_per_child = DEFAULT_MAX_CPU_PER_CHILD;
+    ap_max_data_per_child = DEFAULT_MAX_DATA_PER_CHILD;
+    ap_max_nofile_per_child = DEFAULT_MAX_NOFILE_PER_CHILD;
+    ap_max_rss_per_child = DEFAULT_MAX_RSS_PER_CHILD;
+    ap_max_stack_per_child = DEFAULT_MAX_STACK_PER_CHILD;
     ap_bind_address.s_addr = htonl(INADDR_ANY);
     ap_listeners = NULL;
     ap_listenbacklog = DEFAULT_LISTENBACKLOG;
Index: src/main/http_core.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/src/main/http_core.c,v
retrieving revision 1.20
diff -u -r1.20 http_core.c
--- src/main/http_core.c        2005/02/09 12:13:09     1.20
+++ src/main/http_core.c        2005/11/22 20:44:21
@@ -2191,6 +2191,61 @@
     return NULL;
 }

+static const char *set_child_rl_cpu(cmd_parms *cmd, void *dummy, char *arg)
+{
+    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+    if (err != NULL) {
+        return err;
+    }
+
+    ap_max_cpu_per_child = atoi(arg);
+    return NULL;
+}
+
+static const char *set_child_rl_data(cmd_parms *cmd, void *dummy, char *arg)
+{
+    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+    if (err != NULL) {
+        return err;
+    }
+
+    ap_max_data_per_child = atoi(arg);
+    return NULL;
+}
+
+static const char *set_child_rl_nofile(cmd_parms *cmd, void *dummy, char *arg)
+{
+    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+    if (err != NULL) {
+        return err;
+    }
+
+    ap_max_nofile_per_child = atoi(arg);
+    return NULL;
+}
+
+static const char *set_child_rl_rss(cmd_parms *cmd, void *dummy, char *arg)
+{
+    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+    if (err != NULL) {
+        return err;
+    }
+
+    ap_max_rss_per_child = atoi(arg);
+    return NULL;
+}
+
+static const char *set_child_rl_stack(cmd_parms *cmd, void *dummy, char *arg)
+{
+    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+    if (err != NULL) {
+        return err;
+    }
+
+    ap_max_stack_per_child = atoi(arg);
+    return NULL;
+}
+
 static const char *set_max_requests(cmd_parms *cmd, void *dummy, char *arg)
 {
     const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
@@ -3108,6 +3163,16 @@
   "Maximum number of children alive at the same time" },
 { "MaxRequestsPerChild", set_max_requests, NULL, RSRC_CONF, TAKE1,
   "Maximum number of requests a particular child serves before dying." },
+{ "MaxCPUPerChild", set_child_rl_cpu, NULL, RSRC_CONF, TAKE1,
+  "Maximum amount of CPU time a child can use (rlimit)." },
+{ "MaxDATAPerChild", set_child_rl_data, NULL, RSRC_CONF, TAKE1,
+  "Maximum size of the data segment for a child process (rlimit)." },
+{ "MaxNOFILEPerChild", set_child_rl_nofile, NULL, RSRC_CONF, TAKE1,
+  "Maximum number of open file descriptors a child can have (rlimit)." },
+{ "MaxRSSPerChild", set_child_rl_rss, NULL, RSRC_CONF, TAKE1,
+  "Maximum amount of physical memory a child can use (rlimit)." },
+{ "MaxSTACKPerChild", set_child_rl_stack, NULL, RSRC_CONF, TAKE1,
+  "Maximum amount of stack space a child can use (rlimit)." },
 { "RLimitCPU",
   set_limit_cpu, (void*)XtOffsetOf(core_dir_config, limit_cpu),
   OR_ALL, TAKE12, "Soft/hard limits for max CPU usage in seconds" },
Index: src/main/http_main.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/src/main/http_main.c,v
retrieving revision 1.39
diff -u -r1.39 http_main.c
--- src/main/http_main.c        2005/05/03 05:44:35     1.39
+++ src/main/http_main.c        2005/11/22 20:44:21
@@ -100,6 +100,8 @@
 #include "scoreboard.h"
 #include "multithread.h"
 #include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/resource.h>
 #include <netinet/tcp.h>
 #ifdef MOD_SSL
 #include <openssl/evp.h>
@@ -155,6 +157,11 @@
 API_VAR_EXPORT char *ap_user_name=NULL;
 API_VAR_EXPORT gid_t ap_group_id=0;
 API_VAR_EXPORT int ap_max_requests_per_child=0;
+API_VAR_EXPORT int ap_max_cpu_per_child=0;
+API_VAR_EXPORT int ap_max_data_per_child=0;
+API_VAR_EXPORT int ap_max_nofile_per_child=0;
+API_VAR_EXPORT int ap_max_rss_per_child=0;
+API_VAR_EXPORT int ap_max_stack_per_child=0;
 API_VAR_EXPORT int ap_threads_per_child=0;
 API_VAR_EXPORT int ap_excess_requests_per_child=0;
 API_VAR_EXPORT char *ap_pid_fname=NULL;
@@ -2244,6 +2251,7 @@
     struct sockaddr sa_server;
     struct sockaddr sa_client;
     listen_rec *lr;
+    struct rlimit rlp;

     /* All of initialization is a critical section, we don't care if we're
      * told to HUP or USR1 before we're done initializing.  For example,
@@ -2264,6 +2272,55 @@
     requests_this_child = 0;

     setproctitle("child");
+
+    /*
+     * set up rlimits to keep apache+scripting from leaking horribly
+     */
+    if (ap_max_cpu_per_child != 0){
+       rlp.rlim_cur = rlp.rlim_cur = ap_max_cpu_per_child ;
+       if (setrlimit(RLIMIT_CPU, &rlp) == -1){
+           ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf,
+               "setrlimit: unable to set CPU limit to %d",
+               ap_max_cpu_per_child);
+           clean_child_exit(APEXIT_CHILDFATAL);
+       }
+    }
+    if (ap_max_data_per_child != 0){
+       rlp.rlim_cur = rlp.rlim_cur = ap_max_data_per_child ;
+       if (setrlimit(RLIMIT_DATA, &rlp) == -1){
+           ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf,
+               "setrlimit: unable to set data limit to %d",
+               ap_max_data_per_child);
+           clean_child_exit(APEXIT_CHILDFATAL);
+       }
+    }
+    if (ap_max_nofile_per_child != 0){
+       rlp.rlim_cur = rlp.rlim_cur = ap_max_nofile_per_child ;
+       if (setrlimit(RLIMIT_NOFILE, &rlp) == -1){
+           ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf,
+               "setrlimit: unable to set open file limit to %d",
+               ap_max_nofile_per_child);
+           clean_child_exit(APEXIT_CHILDFATAL);
+       }
+    }
+    if (ap_max_rss_per_child != 0){
+       rlp.rlim_cur = rlp.rlim_cur = ap_max_rss_per_child ;
+       if (setrlimit(RLIMIT_RSS, &rlp) == -1){
+           ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf,
+               "setrlimit: unable to set RSS limit to %d",
+               ap_max_rss_per_child);
+           clean_child_exit(APEXIT_CHILDFATAL);
+       }
+    }
+    if (ap_max_stack_per_child != 0){
+       rlp.rlim_cur = rlp.rlim_cur = ap_max_stack_per_child ;
+       if (setrlimit(RLIMIT_STACK, &rlp) == -1){
+           ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf,
+               "setrlimit: unable to set stack size limit to %d",
+               ap_max_stack_per_child);
+           clean_child_exit(APEXIT_CHILDFATAL);
+       }
+    }

     /* Get a sub pool for global allocations in this child, so that
      * we can have cleanups occur when the child exits.
Index: src/modules/standard/mod_info.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/src/modules/standard/mod_info.c,v
retrieving revision 1.9
diff -u -r1.9 mod_info.c
--- src/modules/standard/mod_info.c     2004/12/02 19:42:48     1.9
+++ src/modules/standard/mod_info.c     2005/11/22 20:44:21
@@ -492,6 +492,15 @@
                         "max: %d</tt><br>\n",
                         ap_daemons_to_start, ap_daemons_min_free,
                         ap_daemons_max_free, ap_daemons_limit);
+            ap_rprintf(r, "<strong>Per-child rlimits:</strong><br>\n"
+                        "<tt>RLIMIT_CPU: %d &nbsp;&nbsp; </tt><br>\n"
+                        "<tt>RLIMIT_DATA: %d &nbsp;&nbsp; </tt><br>\n"
+                        "<tt>RLIMIT_NOFILE: %d &nbsp;&nbsp; </tt><br>\n"
+                        "<tt>RLIMIT_RSS: %d &nbsp;&nbsp; </tt><br>\n"
+                        "<tt>RLIMIT_STACK: %d &nbsp;&nbsp; </tt><br>\n",
+                        ap_max_cpu_per_child, ap_max_data_per_child,
+                        ap_max_nofile_per_child, ap_max_rss_per_child,
+                        ap_max_stack_per_child);
             ap_rprintf(r, "<strong>Max Requests:</strong> "
                         "<tt>per child: %d &nbsp;&nbsp; "
                         "keep alive: %s &nbsp;&nbsp; "
Index: src/support/httpd.exp
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/src/support/httpd.exp,v
retrieving revision 1.9
diff -u -r1.9 httpd.exp
--- src/support/httpd.exp       2003/08/21 13:11:40     1.9
+++ src/support/httpd.exp       2005/11/22 20:44:21
@@ -204,6 +204,11 @@
 ap_make_table
 ap_matches_request_vhost
 ap_max_requests_per_child
+ap_max_cpu_per_child
+ap_max_data_per_child
+ap_max_nofile_per_child
+ap_max_rss_per_child
+ap_max_stack_per_child
 ap_md5
 ap_md5contextTo64
 ap_md5digest



here's hoping gmail doesn't muck it up.

--
GDB has a 'break' feature; why doesn't it have 'fix' too?


--
GDB has a 'break' feature; why doesn't it have 'fix' too?



Visit your host, monkey.org