Пример #1
0
static void master_avail_event(int event, char *context)
{
    MASTER_SERV *serv = (MASTER_SERV *) context;
    time_t  now;

    if (event == 0)				/* XXX Can this happen? */
	msg_panic("master_avail_event: null event");
    else {

	/*
	 * When all servers for a public internet service are busy, we start
	 * creating server processes with "-o stress=yes" on the command
	 * line, and keep creating such processes until the process count is
	 * below the limit for at least 1000 seconds. This provides a minimal
	 * solution that can be adopted into legacy and stable Postfix
	 * releases.
	 * 
	 * This is not the right place to update serv->stress_param_val in
	 * response to stress level changes. Doing so would would contaminate
	 * the "postfix reload" code with stress management implementation
	 * details, creating a source of future bugs. Instead, we update
	 * simple counters or flags here, and use their values to determine
	 * the proper serv->stress_param_val value when exec-ing a server
	 * process.
	 */
	if (serv->stress_param_val != 0
	    && !MASTER_LIMIT_OK(serv->max_proc, serv->total_proc + 1)) {
	    now = event_time();
	    if (serv->stress_expire_time < now)
		master_restart_service(serv, NO_CONF_RELOAD);
	    serv->stress_expire_time = now + 1000;
	}
	master_spawn(serv);
    }
}
Пример #2
0
void    master_config(void)
{
    MASTER_SERV *entry;
    MASTER_SERV *serv;

#define STR_DIFF	strcmp
#define STR_SAME	!strcmp
#define SWAP(type,a,b)	{ type temp = a; a = b; b = temp; }

    /*
     * A service is identified by its endpoint name AND by its transport
     * type, not just by its name alone. The name is unique within its
     * transport type. XXX Service privacy is encoded in the service name.
     */
    set_master_ent();
    while ((entry = get_master_ent()) != 0) {
	if (msg_verbose)
	    print_master_ent(entry);
	for (serv = master_head; serv != 0; serv = serv->next)
	    if (STR_SAME(serv->name, entry->name) && serv->type == entry->type)
		break;

	/*
	 * Add a new service entry. We do not really care in what order the
	 * service entries are kept in memory.
	 */
	if (serv == 0) {
	    entry->next = master_head;
	    master_head = entry;
	    master_start_service(entry);
	}

	/*
	 * Update an existing service entry. Make the current generation of
	 * child processes commit suicide whenever it is convenient. The next
	 * generation of child processes will run with the new configuration
	 * settings.
	 */
	else {
	    serv->flags &= ~MASTER_FLAG_MARK;
	    if (entry->flags & MASTER_FLAG_CONDWAKE)
		serv->flags |= MASTER_FLAG_CONDWAKE;
	    else
		serv->flags &= ~MASTER_FLAG_CONDWAKE;
	    serv->wakeup_time = entry->wakeup_time;
	    serv->max_proc = entry->max_proc;
	    serv->throttle_delay = entry->throttle_delay;
	    SWAP(char *, serv->ext_name, entry->ext_name);
	    SWAP(char *, serv->path, entry->path);
	    SWAP(ARGV *, serv->args, entry->args);
	    SWAP(char *, serv->stress_param_val, entry->stress_param_val);
	    master_restart_service(serv, DO_CONF_RELOAD);
	    free_master_ent(entry);
	}
    }
    end_master_ent();
}