randy       96/07/26 19:49:40

  Modified:    src       http_core.c http_core.h util_script.c
  Log:
  Add resource limiting directives, RLimitCPU, RLimitMEM and RLimitNPROC.
  Reviewed by: Alexei Kosut, Ben Laurie and Robert Thau
  
  Revision  Changes    Path
  1.20      +151 -0    apache/src/http_core.c
  
  Index: http_core.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/http_core.c,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -C3 -r1.19 -r1.20
  *** http_core.c       1996/07/25 19:32:28     1.19
  --- http_core.c       1996/07/27 02:49:34     1.20
  ***************
  *** 94,99 ****
  --- 94,120 ----
        conf->hostname_lookups = 2;/* binary, but will use 2 as an "unset = on" 
*/
        conf->do_rfc1413 = DEFAULT_RFC1413 | 2;  /* set bit 1 to indicate 
default */
    
  + #ifdef RLIMIT_CPU
  +     conf->limit_cpu = (struct rlimit *) pcalloc (a, sizeof (struct rlimit));
  +     if ((getrlimit(RLIMIT_CPU, conf->limit_cpu)) != 0)
  +     conf->limit_cpu = NULL;
  + #endif
  + #ifdef RLIMIT_DATA
  +     conf->limit_mem = (struct rlimit *) pcalloc (a, sizeof (struct rlimit));
  +     if ((getrlimit(RLIMIT_DATA, conf->limit_mem)) != 0)
  +     conf->limit_mem = NULL;
  + #endif
  + #ifdef RLIMIT_VMEM
  +     conf->limit_mem = (struct rlimit *) pcalloc (a, sizeof (struct rlimit));
  +     if ((getrlimit(RLIMIT_VMEM, conf->limit_mem)) != 0)
  +     conf->limit_mem = NULL;
  + #endif
  + #ifdef RLIMIT_NPROC
  +     conf->limit_nproc = (struct rlimit *) pcalloc (a, sizeof (struct 
rlimit));
  +     if ((getrlimit(RLIMIT_NPROC, conf->limit_nproc)) != 0)
  +     conf->limit_nproc = NULL;
  + #endif
  + 
        conf->sec = make_array (a, 2, sizeof(void *));
    
        return (void *)conf;
  ***************
  *** 128,133 ****
  --- 149,164 ----
        if ((new->do_rfc1413 & 2) == 0) conf->do_rfc1413 = new->do_rfc1413;
        if ((new->content_md5 & 2) == 0) conf->content_md5 = new->content_md5;
    
  + #ifdef RLIMIT_CPU
  +     if (new->limit_cpu) conf->limit_cpu = new->limit_cpu;
  + #endif
  + #if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM)
  +     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
  + 
        conf->sec = append_arrays (a, base->sec, new->sec);
    
        return (void*)conf;
  ***************
  *** 808,813 ****
  --- 839,958 ----
        return NULL;
    }
    
  + char *set_limit_cpu (cmd_parms *cmd, core_dir_config *conf, char *arg)
  + {
  + #ifdef RLIMIT_CPU
  +     char *str;
  +     quad_t cur = 0;
  +     quad_t max = 0;
  + 
  +     if ((str = getword_conf(cmd->pool, &arg)))
  +     if (!strcasecmp(str, "max"))
  +         cur = conf->limit_cpu->rlim_max;
  +     else
  +         cur = atol(str);
  +     else {
  +     log_error("Invalid parameters for RLimitCPU", cmd->server);
  +     return NULL;
  +     }
  +     
  +     if ((str = getword_conf(cmd->pool, &arg)))
  +     max = atol(str);
  + 
  +     /* if we aren't running as root, cannot increase max */
  +     if (geteuid()) {
  +     conf->limit_cpu->rlim_cur = cur;
  +     if (max)
  +         log_error("Must be uid 0 to raise maximum RLIMIT_CPU", cmd->server);
  +     }
  +     else {
  +     if (cur)
  +         conf->limit_cpu->rlim_cur = cur;
  +     if (max)
  +         conf->limit_cpu->rlim_max = max;
  +     }
  + #else
  +     log_error("RLimitCPU not supported on this platform", cmd->server);
  + #endif
  +     return NULL;
  + }
  + 
  + char *set_limit_mem (cmd_parms *cmd, core_dir_config *conf, char *arg)
  + {
  + #if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM)
  +     char *str;
  +     quad_t cur = 0;
  +     quad_t max = 0;
  + 
  +     if ((str = getword_conf(cmd->pool, &arg)))
  +     if (!strcasecmp(str, "max"))
  +         cur = conf->limit_mem->rlim_max;
  +     else
  +         cur = atol(str);
  +     else {
  +     log_error("Invalid parameters for RLimitMEM", cmd->server);
  +     return NULL;
  +     }
  +     
  +     if ((str = getword_conf(cmd->pool, &arg)))
  +     max = atol(str);
  + 
  +     /* if we aren't running as root, cannot increase max */
  +     if (geteuid()) {
  +     conf->limit_mem->rlim_cur = cur;
  +     if (max)
  +         log_error("Must be uid 0 to change maximum RLIMIT_MEM", 
cmd->server);
  +     }
  +     else {
  +     if (cur)
  +         conf->limit_mem->rlim_cur = cur;
  +     if (max)
  +         conf->limit_mem->rlim_max = max;
  +     }
  + #else
  +     log_error("RLimitMEM not supported on this platform", cmd->server);
  + #endif
  +     return NULL;
  + }
  + 
  + char *set_limit_nproc (cmd_parms *cmd, core_dir_config *conf, char *arg)
  + {
  + #ifdef RLIMIT_NPROC
  +     char *str;
  +     quad_t cur = 0;
  +     quad_t max = 0;
  + 
  +     if ((str = getword_conf(cmd->pool, &arg)))
  +     if (!strcasecmp(str, "max"))
  +         cur = conf->limit_nproc->rlim_max;
  +     else
  +         cur = atol(str);
  +     else {
  +     log_error("Invalid parameters for RLimitNPROC", cmd->server);
  +     return NULL;
  +     }
  +     
  +     if ((str = getword_conf(cmd->pool, &arg)))
  +     max = atol(str);
  + 
  +     /* if we aren't running as root, cannot increase max */
  +     if (geteuid()) {
  +     conf->limit_nproc->rlim_cur = cur;
  +     if (max)
  +         log_error("Must be uid 0 to raise maximum RLIMIT_NPROC", 
cmd->server);
  +     }
  +     else {
  +     if (cur)
  +         conf->limit_nproc->rlim_cur = cur;
  +     if (max)
  +         conf->limit_nproc->rlim_max = max;
  +     }
  + #else
  +     log_error("RLimitNPROC not supported on this platform", cmd->server);
  + #endif
  +     return NULL;
  + }
  + 
    char *set_bind_address (cmd_parms *cmd, void *dummy, char *arg) {
        bind_address.s_addr = get_virthost_addr (arg, NULL);
        return NULL;
  ***************
  *** 919,924 ****
  --- 1064,1075 ----
    { "ServersSafetyLimit", set_server_limit, NULL, RSRC_CONF, TAKE1, NULL },
    { "MaxClients", set_server_limit, NULL, RSRC_CONF, TAKE1, NULL },
    { "MaxRequestsPerChild", set_max_requests, NULL, RSRC_CONF, TAKE1, NULL },
  + { "RLimitCPU", set_limit_cpu, (void*)XtOffsetOf(core_dir_config, limit_cpu),
  +       OR_ALL, RAW_ARGS, "soft/hard limits for max CPU usage in seconds" },
  + { "RLimitMEM", set_limit_mem, (void*)XtOffsetOf(core_dir_config, limit_mem),
  +       OR_ALL, RAW_ARGS, "soft/hard limits for max memory usage per process" 
},
  + { "RLimitNPROC", set_limit_nproc, (void*)XtOffsetOf(core_dir_config, 
limit_nproc),
  +       OR_ALL, RAW_ARGS, "soft/hard limits for max number of processes per 
uid" },
    { "BindAddress", set_bind_address, NULL, RSRC_CONF, TAKE1,
      "'*', a numeric IP address, or the name of a host with a unique IP 
address"},
    { "Listen", set_listener, NULL, RSRC_CONF, TAKE1,
  
  
  
  1.8       +11 -0     apache/src/http_core.h
  
  Index: http_core.h
  ===================================================================
  RCS file: /export/home/cvs/apache/src/http_core.h,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -C3 -r1.7 -r1.8
  *** http_core.h       1996/07/25 19:32:28     1.7
  --- http_core.h       1996/07/27 02:49:35     1.8
  ***************
  *** 152,157 ****
  --- 152,168 ----
        int hostname_lookups;
        int do_rfc1413;   /* See if client is advertising a username? */
    
  +     /* System Resource Control */
  + #ifdef RLIMIT_CPU
  +     struct rlimit *limit_cpu;
  + #endif
  + #if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM)
  +     struct rlimit *limit_mem;
  + #endif
  + #ifdef RLIMIT_NPROC    
  +     struct rlimit *limit_nproc;
  + #endif
  + 
        /* Access control */
        array_header *sec;
        regex_t *r;
  
  
  
  1.14      +23 -25    apache/src/util_script.c
  
  Index: util_script.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/util_script.c,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -C3 -r1.13 -r1.14
  *** util_script.c     1996/07/21 20:03:45     1.13
  --- util_script.c     1996/07/27 02:49:35     1.14
  ***************
  *** 53,59 ****
  --- 53,62 ----
    
    
    
  + #define CORE_PRIVATE
    #include "httpd.h"
  + #include "http_config.h"
  + #include "http_conf_globals.h"
    #include "http_main.h"
    #include "http_log.h"
    #include "http_protocol.h"
  ***************
  *** 61,66 ****
  --- 64,70 ----
    #include "http_request.h"       /* for sub_req_lookup_uri() */
    #include "util_script.h"
    
  + 
    /*
     * Various utility functions which are common to a whole lot of
     * script-type extensions mechanisms, and might as well be gathered
  ***************
  *** 365,404 ****
    
    void call_exec (request_rec *r, char *argv0, char **env, int shellcmd) 
    {
  !     
  ! #ifdef RLIMIT_CPU
  !     struct rlimit cpulim = { 9, 10 };
  ! #endif
    
  - #ifdef RLIMIT_DATA
  -     struct rlimit datalim = { 2000000, 2500000 };
  - #endif
  - 
  - #ifdef RLIMIT_NPROC
  -     struct rlimit proclim = { 20, 40 };
  - #endif
        
  ! #ifdef RLIMIT_VMEM
  !     struct rlimit vmlim = { 2000000, 2500000 };
  ! #endif
        
  ! #ifdef RLIMIT_CPU
  !     setrlimit (RLIMIT_CPU, &cpulim);
  ! #endif
    
  ! #ifdef RLIMIT_DATA
  !     setrlimit (RLIMIT_DATA, &datalim);
    #endif
  - 
    #ifdef RLIMIT_NPROC
  !     setrlimit (RLIMIT_NPROC, &proclim);
    #endif
  -     
    #ifdef RLIMIT_VMEM
  !     setrlimit (RLIMIT_VMEM, &vmlim);
    #endif
        
  - 
    #ifdef __EMX__    
        if ((!r->args) || (!r->args[0]) || (ind(r->args,'=') >= 0)) {
        int emxloop;
  --- 369,402 ----
    
    void call_exec (request_rec *r, char *argv0, char **env, int shellcmd) 
    {
  !     char *execuser;
    
        
  !     core_dir_config *conf = (core_dir_config *)pcalloc(r->pool, 
sizeof(core_dir_config));
        
  !     conf = (core_dir_config *)get_module_config(r->per_dir_config, 
&core_module);
    
  ! #ifdef RLIMIT_CPU
  !     if (conf->limit_cpu != NULL)
  !     if ((setrlimit (RLIMIT_CPU, conf->limit_cpu)) != 0)
  !         log_unixerr("setrlimit", NULL, "failed to set CPU usage limit", 
r->server);
    #endif
    #ifdef RLIMIT_NPROC
  !     if (conf->limit_nproc != NULL)
  !     if ((setrlimit (RLIMIT_NPROC, conf->limit_nproc)) != 0)
  !         log_unixerr("setrlimit", NULL, "failed to set process limit", 
r->server);
  ! #endif
  ! #ifdef RLIMIT_DATA
  !     if (conf->limit_mem != NULL)
  !     if ((setrlimit (RLIMIT_DATA, conf->limit_mem)) != 0)
  !         log_unixerr("setrlimit", NULL, "failed to set memory usage limit", 
r->server);
    #endif
    #ifdef RLIMIT_VMEM
  !     if (conf->limit_mem != NULL)
  !     if ((setrlimit (RLIMIT_VMEM, conf->limit_mem)) != 0)
  !         log_unixerr("setrlimit", NULL, "failed to set memory usage limit", 
r->server);
    #endif
        
    #ifdef __EMX__    
        if ((!r->args) || (!r->args[0]) || (ind(r->args,'=') >= 0)) {
        int emxloop;
  ***************
  *** 438,444 ****
            execv(r->filename, create_argv(r->pool, argv0, r->args));
        }
    #else
  ! 
        if (shellcmd) 
        execle(SHELL_PATH, SHELL_PATH, "-c", argv0, NULL, env);
    
  --- 436,442 ----
            execv(r->filename, create_argv(r->pool, argv0, r->args));
        }
    #else
  !     
        if (shellcmd) 
        execle(SHELL_PATH, SHELL_PATH, "-c", argv0, NULL, env);
    
  
  
  

Reply via email to