Expand PMF_FN_* macros.
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / master / master_avail.c
blob8eb3f07f2acf528d5c9da9fac04819d578203955
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* master_avail 3
6 /* SUMMARY
7 /* Postfix master - process creation policy
8 /* SYNOPSIS
9 /* #include "master.h"
11 /* void master_avail_listen(serv)
12 /* MASTER_SERV *serv;
14 /* void master_avail_cleanup(serv)
15 /* MASTER_SERV *serv;
17 /* void master_avail_more(serv, proc)
18 /* MASTER_SERV *serv;
19 /* MASTER_PROC *proc;
21 /* void master_avail_less(serv, proc)
22 /* MASTER_SERV *serv;
23 /* MASTER_PROC *proc;
24 /* DESCRIPTION
25 /* This module implements the process creation policy. As long as
26 /* the allowed number of processes for the given service is not
27 /* exceeded, a connection request is either handled by an existing
28 /* available process, or this module causes a new process to be
29 /* created to service the request.
31 /* When the service runs out of process slots, a warning is logged.
32 /* When the service is eligible for stress-mode operation, servers
33 /* are restarted and new servers are created with stress mode enabled.
35 /* master_avail_listen() ensures that someone monitors the service's
36 /* listen socket for connection requests (as long as resources
37 /* to handle connection requests are available). This function may
38 /* be called at random. When the maximum number of servers is running,
39 /* connection requests are left in the system queue.
41 /* master_avail_cleanup() should be called when the named service
42 /* is taken out of operation. It terminates child processes by
43 /* sending SIGTERM.
45 /* master_avail_more() should be called when the named process
46 /* has become available for servicing new connection requests.
48 /* master_avail_less() should be called when the named process
49 /* has become unavailable for servicing new connection requests.
50 /* DIAGNOSTICS
51 /* Panic: internal inconsistencies.
52 /* BUGS
53 /* SEE ALSO
54 /* master_spawn(3), child process birth and death
55 /* LICENSE
56 /* .ad
57 /* .fi
58 /* The Secure Mailer license must be distributed with this software.
59 /* AUTHOR(S)
60 /* Wietse Venema
61 /* IBM T.J. Watson Research
62 /* P.O. Box 704
63 /* Yorktown Heights, NY 10598, USA
64 /*--*/
66 /* System libraries. */
68 #include <sys_defs.h>
70 /* Utility library. */
72 #include <events.h>
73 #include <msg.h>
75 /* Application-specific. */
77 #include "master_proto.h"
78 #include "master.h"
80 /* master_avail_event - create child process to handle connection request */
82 static void master_avail_event(int event, char *context)
84 MASTER_SERV *serv = (MASTER_SERV *) context;
85 time_t now;
86 int n;
88 if (event == 0) /* XXX Can this happen? */
89 return;
90 if (MASTER_THROTTLED(serv)) { /* XXX interface botch */
91 for (n = 0; n < serv->listen_fd_count; n++)
92 event_disable_readwrite(serv->listen_fd[n]);
93 } else {
96 * When all servers for a public internet service are busy, we start
97 * creating server processes with "-o stress=yes" on the command
98 * line, and keep creating such processes until the process count is
99 * below the limit for at least 1000 seconds. This provides a minimal
100 * solution that can be adopted into legacy and stable Postfix
101 * releases.
103 * This is not the right place to update serv->stress_param_val in
104 * response to stress level changes. Doing so would would contaminate
105 * the "postfix reload" code with stress management implementation
106 * details, creating a source of future bugs. Instead, we update
107 * simple counters or flags here, and use their values to determine
108 * the proper serv->stress_param_val value when exec-ing a server
109 * process.
111 if (serv->stress_param_val != 0
112 && !MASTER_LIMIT_OK(serv->max_proc, serv->total_proc + 1)) {
113 now = event_time();
114 if (serv->stress_expire_time < now)
115 master_restart_service(serv);
116 serv->stress_expire_time = now + 1000;
118 master_spawn(serv);
122 /* master_avail_listen - make sure that someone monitors the listen socket */
124 void master_avail_listen(MASTER_SERV *serv)
126 const char *myname = "master_avail_listen";
127 time_t now;
128 int n;
131 * When no-one else is monitoring the service's listen socket, start
132 * monitoring the socket for connection requests. All this under the
133 * restriction that we have sufficient resources to service a connection
134 * request.
136 if (msg_verbose)
137 msg_info("%s: avail %d total %d max %d", myname,
138 serv->avail_proc, serv->total_proc, serv->max_proc);
139 if (serv->avail_proc < 1 && !MASTER_THROTTLED(serv)) {
140 if (MASTER_LIMIT_OK(serv->max_proc, serv->total_proc)) {
141 if (msg_verbose)
142 msg_info("%s: enable events %s", myname, serv->name);
143 for (n = 0; n < serv->listen_fd_count; n++)
144 event_enable_read(serv->listen_fd[n], master_avail_event,
145 (char *) serv);
146 } else if ((serv->flags & MASTER_FLAG_LOCAL_ONLY) == 0
147 && (now = event_time()) - serv->busy_warn_time > 1000) {
148 serv->busy_warn_time = now;
149 msg_warn("service \"%s\" (%s) has reached its process limit \"%d\": "
150 "new clients may experience noticeable delays",
151 serv->ext_name, serv->name, serv->max_proc);
152 msg_warn("to avoid this condition, increase the process count "
153 "in master.cf or reduce the service time per client");
154 if (serv->stress_param_val)
155 msg_warn("see http://www.postfix.org/STRESS_README.html for "
156 "examples of stress-adapting configuration settings");
161 /* master_avail_cleanup - cleanup */
163 void master_avail_cleanup(MASTER_SERV *serv)
165 int n;
167 master_delete_children(serv); /* XXX calls
168 * master_avail_listen */
169 for (n = 0; n < serv->listen_fd_count; n++)
170 event_disable_readwrite(serv->listen_fd[n]); /* XXX must be last */
173 /* master_avail_more - one more available child process */
175 void master_avail_more(MASTER_SERV *serv, MASTER_PROC *proc)
177 const char *myname = "master_avail_more";
178 int n;
181 * This child process has become available for servicing connection
182 * requests, so we can stop monitoring the service's listen socket. The
183 * child will do it for us.
185 if (msg_verbose)
186 msg_info("%s: pid %d (%s)", myname, proc->pid, proc->serv->name);
187 if (proc->avail == MASTER_STAT_AVAIL)
188 msg_panic("%s: process already available", myname);
189 serv->avail_proc++;
190 proc->avail = MASTER_STAT_AVAIL;
191 if (msg_verbose)
192 msg_info("%s: disable events %s", myname, serv->name);
193 for (n = 0; n < serv->listen_fd_count; n++)
194 event_disable_readwrite(serv->listen_fd[n]);
197 /* master_avail_less - one less available child process */
199 void master_avail_less(MASTER_SERV *serv, MASTER_PROC *proc)
201 const char *myname = "master_avail_less";
204 * This child is no longer available for servicing connection requests.
205 * When no child processes are available, start monitoring the service's
206 * listen socket for new connection requests.
208 if (msg_verbose)
209 msg_info("%s: pid %d (%s)", myname, proc->pid, proc->serv->name);
210 if (proc->avail != MASTER_STAT_AVAIL)
211 msg_panic("%s: process not available", myname);
212 serv->avail_proc--;
213 proc->avail = MASTER_STAT_TAKEN;
214 master_avail_listen(serv);