Support a per-location nice value. Note that since we now have two different settings in the per-dir configuration, we need to introduce a merge function. Index: httpd-2.4.1/server/mpm/itk/itk.c =================================================================== --- httpd-2.4.1.orig/server/mpm/itk/itk.c +++ httpd-2.4.1/server/mpm/itk/itk.c @@ -165,11 +165,14 @@ static pid_t ap_my_pid; /* it seems sill static pid_t parent_pid; static int my_child_num; +#define UNSET_NICE_VALUE 100 + typedef struct { uid_t uid; gid_t gid; char *username; + int nice_value; } itk_per_dir_conf; typedef struct @@ -532,6 +535,7 @@ static void child_main(int child_num_arg CAP_SETUID, CAP_SETGID, CAP_DAC_READ_SEARCH, + CAP_SYS_NICE, }; #endif @@ -1554,6 +1558,12 @@ static int itk_post_perdir_config(reques 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 (dconf->nice_value != UNSET_NICE_VALUE && + setpriority(PRIO_PROCESS, 0, dconf->nice_value)) { + _DBG("setpriority(): %s", strerror(errno)); + err = 1; + } + wanted_uid = dconf->uid; wanted_gid = dconf->gid; wanted_username = dconf->username; @@ -1564,7 +1574,7 @@ static int itk_post_perdir_config(reques wanted_username = ap_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(%d): %s", wanted_gid, strerror(errno)); err = 1; @@ -1584,7 +1594,7 @@ static int itk_post_perdir_config(reques */ 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); } @@ -1695,6 +1705,27 @@ static const char *set_max_clients_vhost return NULL; } +static const char *set_nice_value (cmd_parms *cmd, void *ptr, const char *arg) +{ + itk_per_dir_conf *dconf = (itk_per_dir_conf *) ptr; + 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; + } + dconf->nice_value = nice_value; + return NULL; +} + static const command_rec itk_cmds[] = { LISTEN_COMMANDS, AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF, @@ -1713,6 +1744,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|ACCESS_CONF, + "Set nice value for the given vhost, from -20 (highest priority) to 19 (lowest priority)."), AP_GRACEFUL_SHUTDOWN_TIMEOUT_COMMAND, { NULL } }; @@ -1723,6 +1756,32 @@ static void *itk_create_dir_config(apr_p itk_per_dir_conf *c = (itk_per_dir_conf *) apr_pcalloc(p, sizeof(itk_per_dir_conf)); c->uid = c->gid = -1; + c->nice_value = UNSET_NICE_VALUE; + return c; +} + +/* == merge the parent per-dir config structure into ours == */ +static void *itk_merge_dir_config(apr_pool_t *p, void *parent_ptr, void *child_ptr) +{ + itk_per_dir_conf *c = (itk_per_dir_conf *) + itk_create_dir_config(p, NULL); + itk_per_dir_conf *parent = (itk_per_dir_conf *) parent_ptr; + itk_per_dir_conf *child = (itk_per_dir_conf *) child_ptr; + + if (child->username != NULL) { + c->username = child->username; + c->uid = child->uid; + c->gid = child->gid; + } else { + c->username = parent->username; + c->uid = parent->uid; + c->gid = parent->gid; + } + if (child->nice_value != UNSET_NICE_VALUE) { + c->nice_value = child->nice_value; + } else { + c->nice_value = parent->nice_value; + } return c; } @@ -1739,7 +1798,7 @@ AP_DECLARE_MODULE(mpm_itk) = { MPM20_MODULE_STUFF, NULL, /* hook to run before apache parses args */ itk_create_dir_config, /* create per-directory config structure */ - NULL, /* merge per-directory config structures */ + itk_merge_dir_config, /* merge per-directory config structures */ itk_create_server_config, /* create per-server config structure */ NULL, /* merge per-server config structures */ itk_cmds, /* command apr_table_t */