mirror of
https://github.com/samba-team/samba.git
synced 2024-12-29 11:21:54 +03:00
51d4b3c55d
Signed-off-by: Andreas Schneider <asn@samba.org> Signed-off-by: Simo Sorce <idra@samba.org>
296 lines
9.6 KiB
C
296 lines
9.6 KiB
C
/*
|
|
Unix SMB/CIFS implementation.
|
|
Common server globals
|
|
|
|
Copyright (C) Simo Sorce <idra@samba.org> 2011
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "system/network.h"
|
|
#include <tevent.h>
|
|
#include "lib/tsocket/tsocket.h"
|
|
|
|
struct prefork_pool;
|
|
|
|
enum pf_worker_status {
|
|
PF_WORKER_NONE = 0,
|
|
PF_WORKER_ALIVE,
|
|
PF_WORKER_ACCEPTING,
|
|
PF_WORKER_EXITING
|
|
};
|
|
|
|
enum pf_server_cmds {
|
|
PF_SRV_MSG_NONE = 0,
|
|
PF_SRV_MSG_EXIT
|
|
};
|
|
|
|
/**
|
|
* @brief This structure is shared between the controlling parent and the
|
|
* the child. The parent can only write to the 'cmds' and
|
|
* 'allowed_clients' variables, while a child is running.
|
|
* The child can change 'status', and 'num_clients'.
|
|
* All other variables are initialized by the parent before forking the
|
|
* child.
|
|
*/
|
|
struct pf_worker_data {
|
|
pid_t pid;
|
|
enum pf_worker_status status;
|
|
time_t started;
|
|
time_t last_used;
|
|
int num_clients;
|
|
|
|
enum pf_server_cmds cmds;
|
|
int allowed_clients;
|
|
};
|
|
|
|
/**
|
|
* @brief This is the 'main' function called by a child right after the fork.
|
|
* It is daemon specific and should initialize and perform whatever
|
|
* operation the child is meant to do. Returning from this function will
|
|
* cause the termination of the child.
|
|
*
|
|
* @param ev The event context
|
|
* @param msg_ctx The messaging context
|
|
* @param pf The mmaped area used to communicate with parent
|
|
* @param listen_fd_size The number of file descriptors to monitor
|
|
* @param listen_fds The array of file descriptors
|
|
* @param private_data Private data that needs to be passed to the main
|
|
* function from the calling parent.
|
|
*
|
|
* @return Returns the exit status to be reported to the parent via exit()
|
|
*/
|
|
typedef int (prefork_main_fn_t)(struct tevent_context *ev,
|
|
struct messaging_context *msg_ctx,
|
|
struct pf_worker_data *pf,
|
|
int child_id,
|
|
int listen_fd_size,
|
|
int *listen_fds,
|
|
void *private_data);
|
|
|
|
/**
|
|
* @brief Callback function for parents that also want to be called on sigchld
|
|
*
|
|
* @param ev_ctx The event context
|
|
* @param pool The pool handler
|
|
* @param private_data Data private to the parent
|
|
*/
|
|
typedef void (prefork_sigchld_fn_t)(struct tevent_context *ev_ctx,
|
|
struct prefork_pool *pool,
|
|
void *private_data);
|
|
|
|
/* ==== Functions used by controlling process ==== */
|
|
|
|
/**
|
|
* @brief Creates the first pool of preforked processes
|
|
*
|
|
* @param mem_ctx The memory context used to hold the pool structure
|
|
* @param ev_ctx The event context
|
|
* @param msg_ctx The messaging context
|
|
* @param listen_fd_size The number of file descriptors to monitor
|
|
* @param listen_fds The array of file descriptors to monitor
|
|
* @param min_children Minimum number of children that must be available at
|
|
* any given time
|
|
* @param max_children Maximum number of children that can be started. Also
|
|
* determines the initial size of the pool.
|
|
* @param main_fn The children 'main' function to be called after fork
|
|
* @param private_data The children private data.
|
|
* @param pf_pool The allocated pool.
|
|
*
|
|
* @return True if it was successful, False otherwise.
|
|
*
|
|
* NOTE: each listen_fd is forced to non-blocking mode once handed over.
|
|
* You should not toush listen_fds once you hand the to the prefork library.
|
|
*/
|
|
bool prefork_create_pool(TALLOC_CTX *mem_ctx,
|
|
struct tevent_context *ev_ctx,
|
|
struct messaging_context *msg_ctx,
|
|
int listen_fd_size, int *listen_fds,
|
|
int min_children, int max_children,
|
|
prefork_main_fn_t *main_fn, void *private_data,
|
|
struct prefork_pool **pf_pool);
|
|
/**
|
|
* @brief Function used to attempt to expand the size of children.
|
|
*
|
|
* @param pfp The pool structure.
|
|
* @param new_max The new max number of children.
|
|
*
|
|
* @return 0 if operation was successful
|
|
* ENOSPC if the mmap area could not be grown to the requested size
|
|
* EINVAL if the new max is invalid.
|
|
*
|
|
* NOTE: this function can easily fail if the mmap area cannot be enlarged.
|
|
* A well behaving parent MUST NOT error out if this happen.
|
|
*/
|
|
int prefork_expand_pool(struct prefork_pool *pfp, int new_max);
|
|
|
|
/**
|
|
* @brief Used to prefork a number of new children
|
|
*
|
|
* @param ev_ctx The event context
|
|
* @param msg_ctx The messaging context
|
|
* @param pfp The pool structure
|
|
* @param num_children The number of children to be started
|
|
*
|
|
* @return The number of new children effectively forked.
|
|
*
|
|
* NOTE: This method does not expand the pool, if the max number of children
|
|
* has already been forked it will do nothing.
|
|
*/
|
|
int prefork_add_children(struct tevent_context *ev_ctx,
|
|
struct messaging_context *msg_ctx,
|
|
struct prefork_pool *pfp,
|
|
int num_children);
|
|
/**
|
|
* @brief Commands a number of children to stop and exit
|
|
*
|
|
* @param msg_ctx The messaging context.
|
|
* @param pfp The pool.
|
|
* @param num_children The number of children we need to retire.
|
|
* @param age_limit The minimum age a child has been active to be
|
|
* considered for retirement. (Compared against the
|
|
* 'started' value in the pf_worker_data structure of the
|
|
* children.
|
|
*
|
|
* @return Number of children that were signaled to stop
|
|
*
|
|
* NOTE: Only children that have no attached clients can be stopped.
|
|
* If all the available children are too young or are busy then it
|
|
* is possible that none will be asked to stop.
|
|
*/
|
|
int prefork_retire_children(struct messaging_context *msg_ctx,
|
|
struct prefork_pool *pfp,
|
|
int num_children, time_t age_limit);
|
|
/**
|
|
* @brief Count the number of children
|
|
*
|
|
* @param pfp The pool.
|
|
* @param active Number of children currently active if not NULL
|
|
*
|
|
* @return The total number of children.
|
|
*/
|
|
int prefork_count_children(struct prefork_pool *pfp, int *active);
|
|
|
|
/**
|
|
* @brief Count the number of actual connections currently allowed
|
|
*
|
|
* @param pfp The pool.
|
|
*
|
|
* @return The number of connections that can still be opened by clients
|
|
* with the current pool of children.
|
|
*/
|
|
int prefork_count_allowed_connections(struct prefork_pool *pfp);
|
|
|
|
/**
|
|
* @brief Increase the amount of clients each child is allowed to handle
|
|
* simultaneaously. It will allow each child to handle more than
|
|
* one client at a time, up to 'max' (currently set to 100).
|
|
*
|
|
* @param pfp The pool.
|
|
* @param max Max number of allowed connections per child
|
|
*/
|
|
void prefork_increase_allowed_clients(struct prefork_pool *pfp, int max);
|
|
|
|
/**
|
|
* @brief Decrease the amount of clients each child is allowed to handle.
|
|
* Min is 1.
|
|
*
|
|
* @param pfp The pool.
|
|
*/
|
|
void prefork_decrease_allowed_clients(struct prefork_pool *pfp);
|
|
|
|
/**
|
|
* @brief Reset the maximum allowd clients per child to 1.
|
|
* Does not reduce the number of clients actually beeing served by
|
|
* any given child, but prevents children from overcommitting from
|
|
* now on.
|
|
*
|
|
* @param pfp The pool.
|
|
*/
|
|
void prefork_reset_allowed_clients(struct prefork_pool *pfp);
|
|
|
|
/**
|
|
* @brief Send a specific signal to all children.
|
|
* Used to send SIGHUP when a reload of the configuration is needed
|
|
* for example.
|
|
*
|
|
* @param pfp The pool.
|
|
* @param signal_num The signal number to be sent.
|
|
*/
|
|
void prefork_send_signal_to_all(struct prefork_pool *pfp, int signal_num);
|
|
|
|
/**
|
|
* @brief Send a message to all children that the server changed something
|
|
* in the pool and they may want to take action.
|
|
*
|
|
* @param msg_ctx The messaging context.
|
|
* @param pfp The pool.
|
|
*/
|
|
void prefork_warn_active_children(struct messaging_context *msg_ctx,
|
|
struct prefork_pool *pfp);
|
|
|
|
/**
|
|
* @brief Sets the SIGCHLD callback
|
|
*
|
|
* @param pfp The pool handler.
|
|
* @param sigchld_fn The callback function (pass NULL to unset).
|
|
* @param private_data Private data for the callback function.
|
|
*/
|
|
void prefork_set_sigchld_callback(struct prefork_pool *pfp,
|
|
prefork_sigchld_fn_t *sigchld_fn,
|
|
void *private_data);
|
|
|
|
/* ==== Functions used by children ==== */
|
|
|
|
/**
|
|
* @brief Try to listen and accept on one of the listening sockets.
|
|
* Asynchronusly tries to grab the lock and perform an accept.
|
|
* Will automatically update the 'status' of the child and handle
|
|
* all the locking/unlocking/timingout as necessary.
|
|
* Changes behavior depending on whether the child already has other
|
|
* client connections. If not it blocks on the lock call for periods of
|
|
* time. Otherwise it loops on the lock using a timer in order to allow
|
|
* processing of the other clients requests.
|
|
*
|
|
* @param mem_ctx The memory context on whic to allocate the request
|
|
* @param ev The event context
|
|
* @param pf The child/parent shared structure
|
|
* @param listen_fd_size The number of listening file descriptors
|
|
* @param listen_fds The array of listening file descriptors
|
|
*
|
|
* @return The tevent request pointer or NULL on allocation errors.
|
|
*/
|
|
struct tevent_req *prefork_listen_send(TALLOC_CTX *mem_ctx,
|
|
struct tevent_context *ev,
|
|
struct pf_worker_data *pf,
|
|
int listen_fd_size,
|
|
int *listen_fds);
|
|
/**
|
|
* @brief Returns the file descriptor after the new client connection has
|
|
* been accepted.
|
|
*
|
|
* @param req The request
|
|
* @param mem_ctx The memory context for cli_addr and srv_addr
|
|
* @param fd The new file descriptor.
|
|
* @param srv_addr The server address in tsocket_address format
|
|
* @param cli_addr The client address in tsocket_address format
|
|
*
|
|
* @return The error in case the operation failed.
|
|
*/
|
|
int prefork_listen_recv(struct tevent_req *req,
|
|
TALLOC_CTX *mem_ctx, int *fd,
|
|
struct tsocket_address **srv_addr,
|
|
struct tsocket_address **cli_addr);
|
|
|