Support a per-vhost nice value. Index: apache2.2/server/mpm/experimental/itk/itk.c =================================================================== --- apache2.2.orig/server/mpm/experimental/itk/itk.c +++ apache2.2/server/mpm/experimental/itk/itk.c @@ -161,6 +161,7 @@ typedef struct gid_t gid; char *username; int max_clients_vhost; + int nice_value; } itk_server_conf; module AP_MODULE_DECLARE_DATA mpm_itk_module; @@ -507,7 +508,8 @@ static void child_main(int child_num_arg cap_t caps; cap_value_t suidcaps[] = { CAP_SETUID, - CAP_SETGID + CAP_SETGID, + CAP_SYS_NICE }; #endif @@ -1442,6 +1444,11 @@ static int itk_post_read(request_rec *r) 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; + if (setpriority(PRIO_PROCESS, 0, sconf->nice_value)) { + _DBG("setpriority(): %s", strerror(errno)); + err = 1; + } + wanted_uid = sconf->uid; wanted_gid = sconf->gid; wanted_username = sconf->username; @@ -1452,7 +1459,7 @@ static int itk_post_read(request_rec *r) wanted_username = unixd_config.user_name; } - if (wanted_uid != -1 && wanted_gid != -1 && (getuid() != wanted_uid || getgid() != wanted_gid)) { + if (!err && wanted_uid != -1 && wanted_gid != -1 && (getuid() != wanted_uid || getgid() != wanted_gid)) { if (setgid(wanted_gid)) { _DBG("setgid(): %s", strerror(errno)); err = 1; @@ -1472,7 +1479,7 @@ static int itk_post_read(request_rec *r) */ if (err) { ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, \ - "Couldn't set uid/gid, closing connection."); + "Couldn't set uid/gid/priority, closing connection."); ap_lingering_close(r->connection); exit(0); } @@ -1629,6 +1636,28 @@ static const char *set_max_clients_vhost return NULL; } +static const char *set_nice_value (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); + int nice_value = atoi(arg); + + if (nice_value < -20) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: NiceValue of %d is below -20, increasing NiceValue to -20.", + nice_value); + nice_value = -20; + } + else if (nice_value > 19) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: NiceValue of %d is above 19, lowering NiceValue to 19.", + nice_value); + nice_value = 19; + } + sconf->nice_value = nice_value; + return NULL; +} + static const command_rec itk_cmds[] = { UNIX_DAEMON_COMMANDS, LISTEN_COMMANDS, @@ -1646,6 +1675,8 @@ AP_INIT_TAKE2("AssignUserID", assign_use "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."), +AP_INIT_TAKE1("NiceValue", set_nice_value, NULL, RSRC_CONF, + "Set nice value for the given vhost, from -20 (highest priority) to 19 (lowest priority)."), AP_GRACEFUL_SHUTDOWN_TIMEOUT_COMMAND, { NULL } }; @@ -1657,6 +1688,7 @@ static void *itk_create_config(apr_pool_ apr_pcalloc(p, sizeof(itk_server_conf)); c->uid = c->gid = -1; c->max_clients_vhost = -1; + c->nice_value = 0; return c; }