s3-prefork: do not use a lock_fd, just race on accept()
[Samba/bjacke.git] / source3 / lib / server_prefork.h
blob2685f5070000c69597adc678f62c62b7ae07137a
1 /*
2 Unix SMB/CIFS implementation.
3 Common server globals
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"
22 #include <tevent.h>
23 #include "lib/tsocket/tsocket.h"
25 struct prefork_pool;
27 enum pf_worker_status {
28 PF_WORKER_NONE = 0,
29 PF_WORKER_IDLE,
30 PF_WORKER_ACCEPTING,
31 PF_WORKER_BUSY,
32 PF_WORKER_EXITING
35 enum pf_server_cmds {
36 PF_SRV_MSG_NONE = 0,
37 PF_SRV_MSG_EXIT
40 /**
41 * @brief This structure is shared between the controlling parent and the
42 * the child. The parent can only write to the 'cmds' and
43 * 'allowed_clients' variables, while a child is running.
44 * The child can change 'status', and 'num_clients'.
45 * All other variables are initialized by the parent before forking the
46 * child.
48 struct pf_worker_data {
49 pid_t pid;
50 enum pf_worker_status status;
51 time_t started;
52 time_t last_used;
53 int num_clients;
55 enum pf_server_cmds cmds;
56 int allowed_clients;
59 /**
60 * @brief This is the 'main' function called by a child right after the fork.
61 * It is daemon specific and should initialize and perform whatever
62 * operation the child is meant to do. Returning from this function will
63 * cause the termination of the child.
65 * @param ev The event context
66 * @param msg_ctx The messaging context
67 * @param pf The mmaped area used to communicate with parent
68 * @param listen_fd_size The number of file descriptors to monitor
69 * @param listen_fds The array of file descriptors
70 * @param private_data Private data that needs to be passed to the main
71 * function from the calling parent.
73 * @return Returns the exit status to be reported to the parent via exit()
75 typedef int (prefork_main_fn_t)(struct tevent_context *ev,
76 struct messaging_context *msg_ctx,
77 struct pf_worker_data *pf,
78 int child_id,
79 int listen_fd_size,
80 int *listen_fds,
81 void *private_data);
83 /**
84 * @brief Callback function for parents that also want to be called on sigchld
86 * @param ev_ctx The event context
87 * @param pool The pool handler
88 * @param private_data Data private to the parent
90 typedef void (prefork_sigchld_fn_t)(struct tevent_context *ev_ctx,
91 struct prefork_pool *pool,
92 void *private_data);
94 /* ==== Functions used by controlling process ==== */
96 /**
97 * @brief Creates the first pool of preforked processes
99 * @param mem_ctx The memory context used to hold the pool structure
100 * @param ev_ctx The event context
101 * @param msg_ctx The messaging context
102 * @param listen_fd_size The number of file descriptors to monitor
103 * @param listen_fds The array of file descriptors to monitor
104 * @param min_children Minimum number of children that must be available at
105 * any given time
106 * @param max_children Maximum number of children that can be started. Also
107 * determines the initial size of the pool.
108 * @param main_fn The children 'main' function to be called after fork
109 * @param private_data The children private data.
110 * @param pf_pool The allocated pool.
112 * @return True if it was successful, False otherwise.
114 bool prefork_create_pool(TALLOC_CTX *mem_ctx,
115 struct tevent_context *ev_ctx,
116 struct messaging_context *msg_ctx,
117 int listen_fd_size, int *listen_fds,
118 int min_children, int max_children,
119 prefork_main_fn_t *main_fn, void *private_data,
120 struct prefork_pool **pf_pool);
122 * @brief Function used to attempt to expand the size of children.
124 * @param pfp The pool structure.
125 * @param new_max The new max number of children.
127 * @return 0 if operation was successful
128 * ENOSPC if the mmap area could not be grown to the requested size
129 * EINVAL if the new max is invalid.
131 * NOTE: this function can easily fail if the mmap area cannot be enlarged.
132 * A well behaving parent MUST NOT error out if this happen.
134 int prefork_expand_pool(struct prefork_pool *pfp, int new_max);
137 * @brief Used to prefork a number of new children
139 * @param ev_ctx The event context
140 * @param msg_ctx The messaging context
141 * @param pfp The pool structure
142 * @param num_children The number of children to be started
144 * @return The number of new children effectively forked.
146 * NOTE: This method does not expand the pool, if the max number of children
147 * has already been forked it will do nothing.
149 int prefork_add_children(struct tevent_context *ev_ctx,
150 struct messaging_context *msg_ctx,
151 struct prefork_pool *pfp,
152 int num_children);
154 * @brief Commands a number of children to stop and exit
156 * @param pfp The pool.
157 * @param num_children The number of children we need to retire.
158 * @param age_limit The minimum age a child has been active to be
159 * considered for retirement. (Compared against the
160 * 'started' value in the pf_worker_data structure of the
161 * children.
163 * @return Number of children that were signaled to stop
165 * NOTE: Only children that have no attached clients can be stopped.
166 * If all the available children are too young or are busy then it
167 * is possible that none will be asked to stop.
169 int prefork_retire_children(struct prefork_pool *pfp,
170 int num_children, time_t age_limit);
172 * @brief Count the number of active children
174 * @param pfp The pool.
175 * @param total Returns the number of children currently alive
177 * @return The number of children actually serving clients
179 int prefork_count_active_children(struct prefork_pool *pfp, int *total);
182 * @brief Count the number of actual connections currently allowed
184 * @param pfp The pool.
186 * @return The number of connections that can still be opened by clients
187 * with the current pool of children.
189 int prefork_count_allowed_connections(struct prefork_pool *pfp);
192 * @brief Increase the amount of clients each child is allowed to handle
193 * simultaneaously. It will allow each child to handle more than
194 * one client at a time, up to 'max' (currently set to 100).
196 * @param pfp The pool.
197 * @param max Max number of allowed connections per child
199 void prefork_increase_allowed_clients(struct prefork_pool *pfp, int max);
202 * @brief Decrease the amount of clients each child is allowed to handle.
203 * Min is 1.
205 * @param pfp The pool.
207 void prefork_decrease_allowed_clients(struct prefork_pool *pfp);
210 * @brief Reset the maximum allowd clients per child to 1.
211 * Does not reduce the number of clients actually beeing served by
212 * any given child, but prevents children from overcommitting from
213 * now on.
215 * @param pfp The pool.
217 void prefork_reset_allowed_clients(struct prefork_pool *pfp);
220 * @brief Send a specific signal to all children.
221 * Used to send SIGHUP when a reload of the configuration is needed
222 * for example.
224 * @param pfp The pool.
225 * @param signal_num The signal number to be sent.
227 void prefork_send_signal_to_all(struct prefork_pool *pfp, int signal_num);
230 * @brief Sets the SIGCHLD callback
232 * @param pfp The pool handler.
233 * @param sigchld_fn The callback function (pass NULL to unset).
234 * @param private_data Private data for the callback function.
236 void prefork_set_sigchld_callback(struct prefork_pool *pfp,
237 prefork_sigchld_fn_t *sigchld_fn,
238 void *private_data);
240 /* ==== Functions used by children ==== */
243 * @brief Try to listen and accept on one of the listening sockets.
244 * Asynchronusly tries to grab the lock and perform an accept.
245 * Will automatically update the 'status' of the child and handle
246 * all the locking/unlocking/timingout as necessary.
247 * Changes behavior depending on whether the child already has other
248 * client connections. If not it blocks on the lock call for periods of
249 * time. Otherwise it loops on the lock using a timer in order to allow
250 * processing of the other clients requests.
252 * @param mem_ctx The memory context on whic to allocate the request
253 * @param ev The event context
254 * @param pf The child/parent shared structure
255 * @param listen_fd_size The number of listening file descriptors
256 * @param listen_fds The array of listening file descriptors
258 * @return The tevent request pointer or NULL on allocation errors.
260 struct tevent_req *prefork_listen_send(TALLOC_CTX *mem_ctx,
261 struct tevent_context *ev,
262 struct pf_worker_data *pf,
263 int listen_fd_size,
264 int *listen_fds);
266 * @brief Returns the file descriptor after the new client connection has
267 * been accepted.
269 * @param req The request
270 * @param mem_ctx The memory context for cli_addr and srv_addr
271 * @param fd The new file descriptor.
272 * @param srv_addr The server address in tsocket_address format
273 * @param cli_addr The client address in tsocket_address format
275 * @return The error in case the operation failed.
277 int prefork_listen_recv(struct tevent_req *req,
278 TALLOC_CTX *mem_ctx, int *fd,
279 struct tsocket_address **srv_addr,
280 struct tsocket_address **cli_addr);