2 Unix SMB/CIFS implementation.
5 Copyright (C) Simo Sorce <idra@samba.org> 2011
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "system/network.h"
23 #include "lib/tsocket/tsocket.h"
27 enum pf_worker_status
{
40 * @brief This structure is shared between the controlling parent and the
41 * the child. The parent can only write to the 'cmds' and
42 * 'allowed_clients' variables, while a child is running.
43 * The child can change 'status', and 'num_clients'.
44 * All other variables are initialized by the parent before forking the
47 struct pf_worker_data
{
49 enum pf_worker_status status
;
54 enum pf_server_cmds cmds
;
59 * @brief This is the 'main' function called by a child right after the fork.
60 * It is daemon specific and should initialize and perform whatever
61 * operation the child is meant to do. Returning from this function will
62 * cause the termination of the child.
64 * @param ev The event context
65 * @param msg_ctx The messaging context
66 * @param pf The mmaped area used to communicate with parent
67 * @param listen_fd_size The number of file descriptors to monitor
68 * @param listen_fds The array of file descriptors
69 * @param private_data Private data that needs to be passed to the main
70 * function from the calling parent.
72 * @return Returns the exit status to be reported to the parent via exit()
74 typedef int (prefork_main_fn_t
)(struct tevent_context
*ev
,
75 struct messaging_context
*msg_ctx
,
76 struct pf_worker_data
*pf
,
83 * @brief Callback function for parents that also want to be called on sigchld
85 * @param ev_ctx The event context
86 * @param pool The pool handler
87 * @param private_data Data private to the parent
89 typedef void (prefork_sigchld_fn_t
)(struct tevent_context
*ev_ctx
,
90 struct prefork_pool
*pool
,
93 /* ==== Functions used by controlling process ==== */
96 * @brief Creates the first pool of preforked processes
98 * @param mem_ctx The memory context used to hold the pool structure
99 * @param ev_ctx The event context
100 * @param msg_ctx The messaging context
101 * @param listen_fd_size The number of file descriptors to monitor
102 * @param listen_fds The array of file descriptors to monitor
103 * @param min_children Minimum number of children that must be available at
105 * @param max_children Maximum number of children that can be started. Also
106 * determines the initial size of the pool.
107 * @param main_fn The children 'main' function to be called after fork
108 * @param private_data The children private data.
109 * @param pf_pool The allocated pool.
111 * @return True if it was successful, False otherwise.
113 * NOTE: each listen_fd is forced to non-blocking mode once handed over.
114 * You should not toush listen_fds once you hand the to the prefork library.
116 bool prefork_create_pool(TALLOC_CTX
*mem_ctx
,
117 struct tevent_context
*ev_ctx
,
118 struct messaging_context
*msg_ctx
,
119 int listen_fd_size
, int *listen_fds
,
120 int min_children
, int max_children
,
121 prefork_main_fn_t
*main_fn
, void *private_data
,
122 struct prefork_pool
**pf_pool
);
124 * @brief Function used to attempt to expand the size of children.
126 * @param pfp The pool structure.
127 * @param new_max The new max number of children.
129 * @return 0 if operation was successful
130 * ENOSPC if the mmap area could not be grown to the requested size
131 * EINVAL if the new max is invalid.
133 * NOTE: this function can easily fail if the mmap area cannot be enlarged.
134 * A well behaving parent MUST NOT error out if this happen.
136 int prefork_expand_pool(struct prefork_pool
*pfp
, int new_max
);
139 * @brief Used to prefork a number of new children
141 * @param ev_ctx The event context
142 * @param msg_ctx The messaging context
143 * @param pfp The pool structure
144 * @param num_children The number of children to be started
146 * @return The number of new children effectively forked.
148 * NOTE: This method does not expand the pool, if the max number of children
149 * has already been forked it will do nothing.
151 int prefork_add_children(struct tevent_context
*ev_ctx
,
152 struct messaging_context
*msg_ctx
,
153 struct prefork_pool
*pfp
,
156 * @brief Commands a number of children to stop and exit
158 * @param msg_ctx The messaging context.
159 * @param pfp The pool.
160 * @param num_children The number of children we need to retire.
161 * @param age_limit The minimum age a child has been active to be
162 * considered for retirement. (Compared against the
163 * 'started' value in the pf_worker_data structure of the
166 * @return Number of children that were signaled to stop
168 * NOTE: Only children that have no attached clients can be stopped.
169 * If all the available children are too young or are busy then it
170 * is possible that none will be asked to stop.
172 int prefork_retire_children(struct messaging_context
*msg_ctx
,
173 struct prefork_pool
*pfp
,
174 int num_children
, time_t age_limit
);
176 * @brief Count the number of children
178 * @param pfp The pool.
179 * @param active Number of children currently active if not NULL
181 * @return The total number of children.
183 int prefork_count_children(struct prefork_pool
*pfp
, int *active
);
186 * @brief Count the number of actual connections currently allowed
188 * @param pfp The pool.
190 * @return The number of connections that can still be opened by clients
191 * with the current pool of children.
193 int prefork_count_allowed_connections(struct prefork_pool
*pfp
);
196 * @brief Increase the amount of clients each child is allowed to handle
197 * simultaneaously. It will allow each child to handle more than
198 * one client at a time, up to 'max' (currently set to 100).
200 * @param pfp The pool.
201 * @param max Max number of allowed connections per child
203 void prefork_increase_allowed_clients(struct prefork_pool
*pfp
, int max
);
206 * @brief Decrease the amount of clients each child is allowed to handle.
209 * @param pfp The pool.
211 void prefork_decrease_allowed_clients(struct prefork_pool
*pfp
);
214 * @brief Reset the maximum allowd clients per child to 1.
215 * Does not reduce the number of clients actually beeing served by
216 * any given child, but prevents children from overcommitting from
219 * @param pfp The pool.
221 void prefork_reset_allowed_clients(struct prefork_pool
*pfp
);
224 * @brief Send a specific signal to all children.
225 * Used to send SIGHUP when a reload of the configuration is needed
228 * @param pfp The pool.
229 * @param signal_num The signal number to be sent.
231 void prefork_send_signal_to_all(struct prefork_pool
*pfp
, int signal_num
);
234 * @brief Send a message to all children that the server changed something
235 * in the pool and they may want to take action.
237 * @param msg_ctx The messaging context.
238 * @param pfp The pool.
240 void prefork_warn_active_children(struct messaging_context
*msg_ctx
,
241 struct prefork_pool
*pfp
);
244 * @brief Sets the SIGCHLD callback
246 * @param pfp The pool handler.
247 * @param sigchld_fn The callback function (pass NULL to unset).
248 * @param private_data Private data for the callback function.
250 void prefork_set_sigchld_callback(struct prefork_pool
*pfp
,
251 prefork_sigchld_fn_t
*sigchld_fn
,
254 /* ==== Functions used by children ==== */
257 * @brief Try to listen and accept on one of the listening sockets.
258 * Asynchronusly tries to grab the lock and perform an accept.
259 * Will automatically update the 'status' of the child and handle
260 * all the locking/unlocking/timingout as necessary.
261 * Changes behavior depending on whether the child already has other
262 * client connections. If not it blocks on the lock call for periods of
263 * time. Otherwise it loops on the lock using a timer in order to allow
264 * processing of the other clients requests.
266 * @param mem_ctx The memory context on whic to allocate the request
267 * @param ev The event context
268 * @param pf The child/parent shared structure
269 * @param listen_fd_size The number of listening file descriptors
270 * @param listen_fds The array of listening file descriptors
272 * @return The tevent request pointer or NULL on allocation errors.
274 struct tevent_req
*prefork_listen_send(TALLOC_CTX
*mem_ctx
,
275 struct tevent_context
*ev
,
276 struct pf_worker_data
*pf
,
280 * @brief Returns the file descriptor after the new client connection has
283 * @param req The request
284 * @param mem_ctx The memory context for cli_addr and srv_addr
285 * @param fd The new file descriptor.
286 * @param srv_addr The server address in tsocket_address format
287 * @param cli_addr The client address in tsocket_address format
289 * @return The error in case the operation failed.
291 int prefork_listen_recv(struct tevent_req
*req
,
292 TALLOC_CTX
*mem_ctx
, int *fd
,
293 struct tsocket_address
**srv_addr
,
294 struct tsocket_address
**cli_addr
);