2011-04-21 00:28:57 +04:00
/*
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>
2011-07-19 23:07:42 +04:00
# include "lib/tsocket/tsocket.h"
2011-04-21 00:28:57 +04:00
2011-05-20 07:56:02 +04:00
struct prefork_pool ;
2011-04-21 00:28:57 +04:00
enum pf_worker_status {
PF_WORKER_NONE = 0 ,
2011-08-16 19:37:41 +04:00
PF_WORKER_ALIVE ,
2011-04-21 00:28:57 +04:00
PF_WORKER_ACCEPTING ,
PF_WORKER_EXITING
} ;
enum pf_server_cmds {
PF_SRV_MSG_NONE = 0 ,
PF_SRV_MSG_EXIT
} ;
2011-05-16 18:23:59 +04:00
/**
2011-08-10 21:40:18 +04:00
* @ brief This structure is shared between the controlling parent and the
2011-05-16 18:23:59 +04:00
* 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 .
*/
2011-04-21 00:28:57 +04:00
struct pf_worker_data {
pid_t pid ;
enum pf_worker_status status ;
time_t started ;
time_t last_used ;
int num_clients ;
2011-05-06 01:56:31 +04:00
enum pf_server_cmds cmds ;
int allowed_clients ;
2011-04-21 00:28:57 +04:00
} ;
2011-05-16 18:23:59 +04:00
/**
* @ 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
2011-07-18 18:39:50 +04:00
* @ param msg_ctx The messaging context
2011-05-16 18:23:59 +04:00
* @ 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 ( )
*/
2011-04-21 00:28:57 +04:00
typedef int ( prefork_main_fn_t ) ( struct tevent_context * ev ,
2011-07-18 18:39:50 +04:00
struct messaging_context * msg_ctx ,
2011-04-21 00:28:57 +04:00
struct pf_worker_data * pf ,
2011-08-05 18:34:05 +04:00
int child_id ,
2011-05-10 16:39:14 +04:00
int listen_fd_size ,
int * listen_fds ,
2011-04-21 00:28:57 +04:00
void * private_data ) ;
2011-05-20 07:56:02 +04:00
/**
* @ 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 ) ;
2011-04-21 00:28:57 +04:00
/* ==== Functions used by controlling process ==== */
2011-05-16 18:23:59 +04:00
/**
* @ brief Creates the first pool of preforked processes
*
* @ param mem_ctx The memory context used to hold the pool structure
2011-07-18 18:39:50 +04:00
* @ param ev_ctx The event context
* @ param msg_ctx The messaging context
2011-05-16 18:23:59 +04:00
* @ 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 .
2011-08-18 20:35:02 +04:00
*
* 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 .
2011-05-16 18:23:59 +04:00
*/
2011-07-18 18:39:50 +04:00
bool prefork_create_pool ( TALLOC_CTX * mem_ctx ,
struct tevent_context * ev_ctx ,
struct messaging_context * msg_ctx ,
2011-05-10 16:39:14 +04:00
int listen_fd_size , int * listen_fds ,
2011-04-21 00:28:57 +04:00
int min_children , int max_children ,
prefork_main_fn_t * main_fn , void * private_data ,
struct prefork_pool * * pf_pool ) ;
2011-05-16 18:23:59 +04:00
/**
2011-08-10 21:40:18 +04:00
* @ brief Function used to attempt to expand the size of children .
2011-05-16 18:23:59 +04:00
*
* @ 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 .
*
2011-08-10 21:40:18 +04:00
* NOTE : this function can easily fail if the mmap area cannot be enlarged .
2011-05-16 18:23:59 +04:00
* A well behaving parent MUST NOT error out if this happen .
*/
2011-05-09 12:51:47 +04:00
int prefork_expand_pool ( struct prefork_pool * pfp , int new_max ) ;
2011-04-21 00:28:57 +04:00
2011-05-16 18:23:59 +04:00
/**
* @ brief Used to prefork a number of new children
*
* @ param ev_ctx The event context
2011-07-18 18:39:50 +04:00
* @ param msg_ctx The messaging context
2011-05-16 18:23:59 +04:00
* @ 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 .
*/
2011-04-21 00:28:57 +04:00
int prefork_add_children ( struct tevent_context * ev_ctx ,
2011-07-18 18:39:50 +04:00
struct messaging_context * msg_ctx ,
2011-04-21 00:28:57 +04:00
struct prefork_pool * pfp ,
int num_children ) ;
2011-05-16 18:23:59 +04:00
/**
2011-08-10 21:40:18 +04:00
* @ brief Commands a number of children to stop and exit
2011-05-16 18:23:59 +04:00
*
2011-08-18 18:31:36 +04:00
* @ param msg_ctx The messaging context .
2011-05-16 18:23:59 +04:00
* @ 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
*
2011-08-10 21:40:18 +04:00
* NOTE : Only children that have no attached clients can be stopped .
* If all the available children are too young or are busy then it
2011-05-16 18:23:59 +04:00
* is possible that none will be asked to stop .
*/
2011-08-18 18:31:36 +04:00
int prefork_retire_children ( struct messaging_context * msg_ctx ,
struct prefork_pool * pfp ,
2011-04-21 00:28:57 +04:00
int num_children , time_t age_limit ) ;
2011-05-16 18:23:59 +04:00
/**
2011-08-17 02:20:51 +04:00
* @ brief Count the number of children
2011-05-16 18:23:59 +04:00
*
* @ param pfp The pool .
2011-08-17 02:20:51 +04:00
* @ param active Number of children currently active if not NULL
2011-05-16 18:23:59 +04:00
*
2011-08-17 02:20:51 +04:00
* @ return The total number of children .
2011-05-16 18:23:59 +04:00
*/
2011-08-17 02:20:51 +04:00
int prefork_count_children ( struct prefork_pool * pfp , int * active ) ;
2011-05-16 18:46:35 +04:00
2011-05-16 18:23:59 +04:00
/**
2011-08-12 20:24:13 +04:00
* @ 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 ) .
2011-05-16 18:23:59 +04:00
*
* @ param pfp The pool .
2011-08-12 20:24:13 +04:00
* @ param max Max number of allowed connections per child
2011-05-16 18:23:59 +04:00
*/
2011-05-06 01:56:31 +04:00
void prefork_increase_allowed_clients ( struct prefork_pool * pfp , int max ) ;
2011-05-16 18:23:59 +04:00
2011-08-12 20:24:13 +04:00
/**
* @ 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 ) ;
2011-05-16 18:23:59 +04:00
/**
* @ 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 .
*/
2011-05-06 01:56:31 +04:00
void prefork_reset_allowed_clients ( struct prefork_pool * pfp ) ;
2011-05-16 18:23:59 +04:00
/**
* @ 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 .
*/
2011-05-09 16:49:50 +04:00
void prefork_send_signal_to_all ( struct prefork_pool * pfp , int signal_num ) ;
2011-04-21 00:28:57 +04:00
2011-08-17 23:21:12 +04:00
/**
* @ 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 ) ;
2011-05-20 07:56:02 +04:00
/**
* @ 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 ) ;
2011-04-21 00:28:57 +04:00
/* ==== Functions used by children ==== */
2011-05-16 18:23:59 +04:00
/**
* @ brief Try to listen and accept on one of the listening sockets .
* Asynchronusly tries to grab the lock and perform an accept .
2011-08-10 21:40:18 +04:00
* Will automatically update the ' status ' of the child and handle
2011-05-16 18:23:59 +04:00
* 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 .
*/
2011-05-04 02:55:25 +04:00
struct tevent_req * prefork_listen_send ( TALLOC_CTX * mem_ctx ,
struct tevent_context * ev ,
struct pf_worker_data * pf ,
2011-05-10 16:39:14 +04:00
int listen_fd_size ,
2011-08-16 17:30:28 +04:00
int * listen_fds ) ;
2011-05-16 18:23:59 +04:00
/**
* @ brief Returns the file descriptor after the new client connection has
* been accepted .
*
2011-07-19 23:07:42 +04:00
* @ 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
2011-05-16 18:23:59 +04:00
*
* @ return The error in case the operation failed .
*/
2011-07-19 23:07:42 +04:00
int prefork_listen_recv ( struct tevent_req * req ,
TALLOC_CTX * mem_ctx , int * fd ,
struct tsocket_address * * srv_addr ,
struct tsocket_address * * cli_addr ) ;