mirror of
https://github.com/apache/httpd.git
synced 2025-07-25 17:01:22 +00:00
Add the resource limiting code back to Apache 2.0. This only works on
Unix because I can't find any other platforms with rlimit. If there are other platforms that need this code, then some of the code needs to move. This has just barely been tested, so it could probably use some good testing. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@85449 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
4
STATUS
4
STATUS
@ -1,5 +1,5 @@
|
||||
Apache 2.0 STATUS:
|
||||
Last modified at [$Date: 2000/06/05 19:43:57 $]
|
||||
Last modified at [$Date: 2000/06/06 21:45:07 $]
|
||||
|
||||
Release:
|
||||
|
||||
@ -23,8 +23,6 @@ RELEASE SHOWSTOPPERS:
|
||||
module. This should be override-able of course.
|
||||
Status: Jim Jagielski is looking into this.
|
||||
|
||||
* Put back resource limit code
|
||||
|
||||
* suEXEC doesn't work
|
||||
Status: Manoj has posted an patch to fix this.
|
||||
<19991103003605.A20612@samosa.mindspring.com>
|
||||
|
@ -256,6 +256,16 @@ typedef struct {
|
||||
unsigned add_default_charset : 2;
|
||||
char *add_default_charset_name;
|
||||
|
||||
/* System Resource Control */
|
||||
#ifdef RLIMIT_CPU
|
||||
struct rlimit *limit_cpu;
|
||||
#endif
|
||||
#if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS)
|
||||
struct rlimit *limit_mem;
|
||||
#endif
|
||||
#ifdef RLIMIT_NPROC
|
||||
struct rlimit *limit_nproc;
|
||||
#endif
|
||||
unsigned long limit_req_body; /* limit on bytes in request msg body */
|
||||
|
||||
/* logging options */
|
||||
|
@ -76,6 +76,8 @@
|
||||
* -Doug MacEachern
|
||||
*/
|
||||
|
||||
#define CORE_PRIVATE
|
||||
|
||||
#ifdef USE_PERL_SSI
|
||||
#include "config.h"
|
||||
#undef VOIDUSED
|
||||
@ -94,6 +96,7 @@
|
||||
#include "http_log.h"
|
||||
#include "http_main.h"
|
||||
#include "util_script.h"
|
||||
#include "http_core.h"
|
||||
#include <string.h>
|
||||
#ifdef HAVE_PWD_H
|
||||
#include <pwd.h>
|
||||
@ -828,6 +831,12 @@ static int include_cmd(char *s, request_rec *r)
|
||||
char **argv;
|
||||
ap_file_t *file = NULL;
|
||||
ap_iol *iol;
|
||||
#if defined(RLIMIT_CPU) || defined(RLIMIT_NPROC) || \
|
||||
defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined (RLIMIT_AS)
|
||||
core_dir_config *conf;
|
||||
conf = (core_dir_config *) ap_get_module_config(r->per_dir_config,
|
||||
&core_module);
|
||||
#endif
|
||||
|
||||
arg.r = r;
|
||||
arg.s = s;
|
||||
@ -863,6 +872,15 @@ static int include_cmd(char *s, request_rec *r)
|
||||
(ap_setprocattr_io(procattr, APR_NO_PIPE,
|
||||
APR_FULL_BLOCK, APR_NO_PIPE) != APR_SUCCESS) ||
|
||||
(ap_setprocattr_dir(procattr, ap_make_dirstr_parent(r->pool, r->filename)) != APR_SUCCESS) ||
|
||||
#ifdef RLIMIT_CPU
|
||||
((rc = ap_setprocattr_limit(procattr, APR_LIMIT_CPU, conf->limit_cpu)) != APR_SUCCESS) ||
|
||||
#endif
|
||||
#if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS)
|
||||
((rc = ap_setprocattr_limit(procattr, APR_LIMIT_MEM, conf->limit_mem)) != APR_SUCCESS) ||
|
||||
#endif
|
||||
#ifdef RLIMIT_NPROC
|
||||
((rc = ap_setprocattr_limit(procattr, APR_LIMIT_NPROC, conf->limit_nproc)) != APR_SUCCESS) ||
|
||||
#endif
|
||||
(ap_setprocattr_cmdtype(procattr, APR_SHELLCMD) != APR_SUCCESS)) {
|
||||
/* Something bad happened, tell the world. */
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, errno, r,
|
||||
|
@ -69,6 +69,8 @@
|
||||
* they fail.
|
||||
*/
|
||||
|
||||
#define CORE_PRIVATE
|
||||
|
||||
#include "ap_config.h"
|
||||
#include "httpd.h"
|
||||
#include "http_config.h"
|
||||
@ -305,6 +307,12 @@ static ap_status_t run_cgi_child(BUFF **script_out, BUFF **script_in, BUFF **scr
|
||||
ap_status_t rc = APR_SUCCESS;
|
||||
ap_file_t *file = NULL;
|
||||
ap_iol *iol;
|
||||
#if defined(RLIMIT_CPU) || defined(RLIMIT_NPROC) || \
|
||||
defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined (RLIMIT_AS)
|
||||
core_dir_config *conf;
|
||||
conf = (core_dir_config *) ap_get_module_config(r->per_dir_config, &core_module);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef DEBUG_CGI
|
||||
#ifdef OS2
|
||||
@ -341,6 +349,15 @@ static ap_status_t run_cgi_child(BUFF **script_out, BUFF **script_in, BUFF **scr
|
||||
APR_CHILD_BLOCK)) != APR_SUCCESS) ||
|
||||
((rc = ap_setprocattr_dir(procattr,
|
||||
ap_make_dirstr_parent(r->pool, r->filename))) != APR_SUCCESS) ||
|
||||
#ifdef RLIMIT_CPU
|
||||
((rc = ap_setprocattr_limit(procattr, APR_LIMIT_CPU, conf->limit_cpu)) != APR_SUCCESS) ||
|
||||
#endif
|
||||
#if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS)
|
||||
((rc = ap_setprocattr_limit(procattr, APR_LIMIT_MEM, conf->limit_mem)) != APR_SUCCESS) ||
|
||||
#endif
|
||||
#ifdef RLIMIT_NPROC
|
||||
((rc = ap_setprocattr_limit(procattr, APR_LIMIT_NPROC, conf->limit_nproc)) != APR_SUCCESS) ||
|
||||
#endif
|
||||
((rc = ap_setprocattr_cmdtype(procattr, APR_PROGRAM)) != APR_SUCCESS)) {
|
||||
/* Something bad happened, tell the world. */
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r,
|
||||
|
@ -72,6 +72,7 @@
|
||||
#include "apr_fnmatch.h"
|
||||
#include "http_connection.h"
|
||||
#include "util_ebcdic.h"
|
||||
#include "mpm.h"
|
||||
|
||||
/* Allow Apache to use ap_mmap */
|
||||
#ifdef USE_MMAP_FILES
|
||||
@ -140,6 +141,16 @@ static void *create_core_dir_config(ap_pool_t *a, char *dir)
|
||||
conf->do_rfc1413 = DEFAULT_RFC1413 | 2; /* set bit 1 to indicate default */
|
||||
conf->satisfy = SATISFY_NOSPEC;
|
||||
|
||||
#ifdef RLIMIT_CPU
|
||||
conf->limit_cpu = NULL;
|
||||
#endif
|
||||
#if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS)
|
||||
conf->limit_mem = NULL;
|
||||
#endif
|
||||
#ifdef RLIMIT_NPROC
|
||||
conf->limit_nproc = NULL;
|
||||
#endif
|
||||
|
||||
conf->limit_req_body = 0;
|
||||
conf->sec = ap_make_array(a, 2, sizeof(void *));
|
||||
#ifdef WIN32
|
||||
@ -243,6 +254,22 @@ static void *merge_core_dir_configs(ap_pool_t *a, void *basev, void *newv)
|
||||
conf->use_canonical_name = new->use_canonical_name;
|
||||
}
|
||||
|
||||
#ifdef RLIMIT_CPU
|
||||
if (new->limit_cpu) {
|
||||
conf->limit_cpu = new->limit_cpu;
|
||||
}
|
||||
#endif
|
||||
#if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS)
|
||||
if (new->limit_mem) {
|
||||
conf->limit_mem = new->limit_mem;
|
||||
}
|
||||
#endif
|
||||
#ifdef RLIMIT_NPROC
|
||||
if (new->limit_nproc) {
|
||||
conf->limit_nproc = new->limit_nproc;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (new->limit_req_body) {
|
||||
conf->limit_req_body = new->limit_req_body;
|
||||
}
|
||||
@ -2225,6 +2252,49 @@ static const char *set_interpreter_source(cmd_parms *cmd, core_dir_config *d,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined (RLIMIT_CPU) || !(defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS)) || !defined (RLIMIT_NPROC)
|
||||
static const char *no_set_limit(cmd_parms *cmd, core_dir_config *conf,
|
||||
char *arg, char *arg2)
|
||||
{
|
||||
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, cmd->server,
|
||||
"%s not supported on this platform", cmd->cmd->name);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef RLIMIT_CPU
|
||||
static const char *set_limit_cpu(cmd_parms *cmd, core_dir_config *conf,
|
||||
char *arg, char *arg2)
|
||||
{
|
||||
unixd_set_rlimit(cmd, &conf->limit_cpu, arg, arg2, RLIMIT_CPU);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS)
|
||||
static const char *set_limit_mem(cmd_parms *cmd, core_dir_config *conf,
|
||||
char *arg, char * arg2)
|
||||
{
|
||||
#if defined(RLIMIT_AS)
|
||||
unixd_set_rlimit(cmd, &conf->limit_mem, arg, arg2 ,RLIMIT_AS);
|
||||
#elif defined(RLIMIT_DATA)
|
||||
unixd_set_rlimit(cmd, &conf->limit_mem, arg, arg2, RLIMIT_DATA);
|
||||
#elif defined(RLIMIT_VMEM)
|
||||
unixd_set_rlimit(cmd, &conf->limit_mem, arg, arg2, RLIMIT_VMEM);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef RLIMIT_NPROC
|
||||
static const char *set_limit_nproc(cmd_parms *cmd, core_dir_config *conf,
|
||||
char *arg, char * arg2)
|
||||
{
|
||||
unixd_set_rlimit(cmd, &conf->limit_nproc, arg, arg2, RLIMIT_NPROC);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Note --- ErrorDocument will now work from .htaccess files.
|
||||
* The AllowOverride of Fileinfo allows webmasters to turn it off
|
||||
*/
|
||||
@ -2363,6 +2433,28 @@ static const command_rec core_cmds[] = {
|
||||
(void*)XtOffsetOf(core_dir_config, limit_req_body),
|
||||
OR_ALL, TAKE1,
|
||||
"Limit (in bytes) on maximum size of request message body" },
|
||||
/* System Resource Controls */
|
||||
{ "RLimitCPU",
|
||||
#ifdef RLIMIT_CPU
|
||||
set_limit_cpu, (void*)XtOffsetOf(core_dir_config, limit_cpu),
|
||||
#else
|
||||
no_set_limit, NULL,
|
||||
#endif
|
||||
OR_ALL, TAKE12, "Soft/hard limits for max CPU usage in seconds" },
|
||||
{ "RLimitMEM",
|
||||
#if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined (RLIMIT_AS)
|
||||
set_limit_mem, (void*)XtOffsetOf(core_dir_config, limit_mem),
|
||||
#else
|
||||
no_set_limit, NULL,
|
||||
#endif
|
||||
OR_ALL, TAKE12, "Soft/hard limits for max memory usage per process" },
|
||||
{ "RLimitNPROC",
|
||||
#ifdef RLIMIT_NPROC
|
||||
set_limit_nproc, (void*)XtOffsetOf(core_dir_config, limit_nproc),
|
||||
#else
|
||||
no_set_limit, NULL,
|
||||
#endif
|
||||
OR_ALL, TAKE12, "soft/hard limits for max number of processes per uid" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
@ -63,6 +63,8 @@
|
||||
#include "http_log.h"
|
||||
#include "unixd.h"
|
||||
#include <pwd.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
unixd_config_rec unixd_config;
|
||||
|
||||
@ -394,4 +396,60 @@ void unixd_siglist_init(void)
|
||||
ap_sys_siglist[sig] = "";
|
||||
}
|
||||
#endif /* NEED_AP_SYS_SIGLIST */
|
||||
|
||||
|
||||
#if defined(RLIMIT_CPU) || defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_NPROC) || defined(RLIMIT_AS)
|
||||
API_EXPORT(void) unixd_set_rlimit(cmd_parms *cmd, struct rlimit **plimit,
|
||||
const char *arg, const char * arg2, int type)
|
||||
{
|
||||
char *str;
|
||||
struct rlimit *limit;
|
||||
/* If your platform doesn't define rlim_t then typedef it in ap_config.h */
|
||||
rlim_t cur = 0;
|
||||
rlim_t max = 0;
|
||||
|
||||
*plimit = (struct rlimit *)ap_pcalloc(cmd->pool, sizeof(**plimit));
|
||||
limit = *plimit;
|
||||
if ((getrlimit(type, limit)) != 0) {
|
||||
*plimit = NULL;
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, cmd->server,
|
||||
"%s: getrlimit failed", cmd->cmd->name);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((str = ap_getword_conf(cmd->pool, &arg))) {
|
||||
if (!strcasecmp(str, "max")) {
|
||||
cur = limit->rlim_max;
|
||||
}
|
||||
else {
|
||||
cur = atol(str);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, cmd->server,
|
||||
"Invalid parameters for %s", cmd->cmd->name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (arg2 && (str = ap_getword_conf(cmd->pool, &arg2))) {
|
||||
max = atol(str);
|
||||
}
|
||||
|
||||
/* if we aren't running as root, cannot increase max */
|
||||
if (geteuid()) {
|
||||
limit->rlim_cur = cur;
|
||||
if (max) {
|
||||
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, cmd->server,
|
||||
"Must be uid 0 to raise maximum %s", cmd->cmd->name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (cur) {
|
||||
limit->rlim_cur = cur;
|
||||
}
|
||||
if (max) {
|
||||
limit->rlim_max = max;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -60,6 +60,7 @@
|
||||
#define UNIXD_H
|
||||
|
||||
#include "httpd.h"
|
||||
#include <sys/resource.h>
|
||||
|
||||
/* common stuff that unix MPMs will want */
|
||||
|
||||
@ -85,6 +86,11 @@ int unixd_setup_child(void);
|
||||
void unixd_pre_config(void);
|
||||
const char *unixd_set_user(cmd_parms *cmd, void *dummy, char *arg);
|
||||
const char *unixd_set_group(cmd_parms *cmd, void *dummy, char *arg);
|
||||
#if defined(RLIMIT_CPU) || defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || \
|
||||
defined(RLIMIT_NPROC) || defined(RLIMIT_AS)
|
||||
API_EXPORT(void) unixd_set_rlimit(cmd_parms *cmd, struct rlimit **plimit,
|
||||
const char *arg, const char * arg2, int type);
|
||||
#endif
|
||||
|
||||
/* Information on signals for the various platforms */
|
||||
|
||||
|
@ -58,6 +58,7 @@
|
||||
|
||||
#include "httpd.h"
|
||||
#include "mpm_default.h"
|
||||
#include "unixd.h"
|
||||
|
||||
#ifndef APACHE_MPM_DEXTER_H
|
||||
#define APACHE_MPM_DEXTER_H
|
||||
|
@ -56,6 +56,7 @@
|
||||
* University of Illinois, Urbana-Champaign.
|
||||
*/
|
||||
#include "scoreboard.h"
|
||||
#include "unixd.h"
|
||||
|
||||
#ifndef APACHE_MPM_MPMT_PTHREAD_H
|
||||
#define APACHE_MPM_MPMT_PTHREAD_H
|
||||
|
@ -59,6 +59,7 @@
|
||||
#include "httpd.h"
|
||||
#include "mpm_default.h"
|
||||
#include "scoreboard.h"
|
||||
#include "unixd.h"
|
||||
|
||||
#ifndef APACHE_MPM_PREFORK_H
|
||||
#define APACHE_MPM_PREFORK_H
|
||||
|
Reference in New Issue
Block a user