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); } }
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(); }