Enforce the per-vhost server limit. Index: httpd-2.0.55/server/mpm/experimental/itk/itk.c =================================================================== --- httpd-2.0.55.orig/server/mpm/experimental/itk/itk.c +++ httpd-2.0.55/server/mpm/experimental/itk/itk.c @@ -154,6 +154,7 @@ typedef struct uid_t uid; gid_t gid; char *username; + int max_clients_vhost; } itk_server_conf; module AP_MODULE_DECLARE_DATA mpm_itk_module; @@ -1250,6 +1251,23 @@ static int itk_post_read(request_rec *r) itk_server_conf *sconf = (itk_server_conf *) ap_get_module_config(r->server->module_config, &mpm_itk_module); + /* Enforce MaxClientsVhost. */ + if (sconf->max_clients_vhost > 0) { + int i, num_other_servers = 0; + for (i = 0; i < ap_daemons_limit; ++i) { + worker_score *ws = &ap_scoreboard_image->servers[i][0]; + if (ws->status >= SERVER_BUSY_READ && strncmp(ws->vhost, r->server->server_hostname, 31) == 0) + ++num_other_servers; + } + + if (num_other_servers > sconf->max_clients_vhost) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, \ + "MaxClientsVhost reached for %s, refusing client.", + r->server->server_hostname); + return HTTP_SERVICE_UNAVAILABLE; + } + } + strncpy(ap_scoreboard_image->servers[my_child_num][0].vhost, r->server->server_hostname, 31); ap_scoreboard_image->servers[my_child_num][0].vhost[31] = 0; @@ -1432,6 +1450,14 @@ static const char *assign_user_id (cmd_p return NULL; } +static const char *set_max_clients_vhost (cmd_parms *cmd, void *dummy, const char *arg) +{ + itk_server_conf *sconf = + (itk_server_conf *) ap_get_module_config(cmd->server->module_config, &mpm_itk_module); + sconf->max_clients_vhost = atoi(arg); + return NULL; +} + static const command_rec itk_cmds[] = { UNIX_DAEMON_COMMANDS, LISTEN_COMMANDS, @@ -1447,6 +1473,8 @@ AP_INIT_TAKE1("ServerLimit", set_server_ "Maximum value of MaxClients for this run of Apache"), AP_INIT_TAKE2("AssignUserID", assign_user_id, NULL, RSRC_CONF, "Tie a virtual host to a specific child process."), +AP_INIT_TAKE1("MaxClientsVHost", set_max_clients_vhost, NULL, RSRC_CONF, + "Maximum number of children alive at the same time for this virtual host."), { NULL } }; @@ -1456,6 +1484,7 @@ static void *itk_create_config(apr_pool_ itk_server_conf *c = (itk_server_conf *) apr_pcalloc(p, sizeof(itk_server_conf)); c->uid = c->gid = -1; + c->max_clients_vhost = -1; return c; }