mirror of
https://github.com/samba-team/samba.git
synced 2025-02-24 13:57:43 +03:00
s3-prefork: Pass messaging context around too
Pair-Programmed-With: Andreas Schneider <asn@samba.org> Signed-off-by: Andreas Schneider <asn@samba.org>
This commit is contained in:
parent
1155280a48
commit
2b33b438ba
@ -54,7 +54,9 @@ static int prefork_pool_destructor(struct prefork_pool *pfp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool prefork_create_pool(struct tevent_context *ev_ctx, TALLOC_CTX *mem_ctx,
|
||||
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,
|
||||
@ -118,7 +120,8 @@ bool prefork_create_pool(struct tevent_context *ev_ctx, TALLOC_CTX *mem_ctx,
|
||||
case 0: /* THE CHILD */
|
||||
|
||||
pfp->pool[i].status = PF_WORKER_IDLE;
|
||||
ret = pfp->main_fn(ev_ctx, &pfp->pool[i],
|
||||
ret = pfp->main_fn(ev_ctx, msg_ctx,
|
||||
&pfp->pool[i],
|
||||
pfp->listen_fd_size,
|
||||
pfp->listen_fds,
|
||||
pfp->lock_fd,
|
||||
@ -175,6 +178,7 @@ int prefork_expand_pool(struct prefork_pool *pfp, int new_max)
|
||||
}
|
||||
|
||||
int prefork_add_children(struct tevent_context *ev_ctx,
|
||||
struct messaging_context *msg_ctx,
|
||||
struct prefork_pool *pfp,
|
||||
int num_children)
|
||||
{
|
||||
@ -201,7 +205,8 @@ int prefork_add_children(struct tevent_context *ev_ctx,
|
||||
case 0: /* THE CHILD */
|
||||
|
||||
pfp->pool[i].status = PF_WORKER_IDLE;
|
||||
ret = pfp->main_fn(ev_ctx, &pfp->pool[i],
|
||||
ret = pfp->main_fn(ev_ctx, msg_ctx,
|
||||
&pfp->pool[i],
|
||||
pfp->listen_fd_size,
|
||||
pfp->listen_fds,
|
||||
pfp->lock_fd,
|
||||
|
@ -62,6 +62,7 @@ struct pf_worker_data {
|
||||
* 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
|
||||
@ -72,6 +73,7 @@ struct pf_worker_data {
|
||||
* @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 listen_fd_size,
|
||||
int *listen_fds,
|
||||
@ -94,8 +96,9 @@ typedef void (prefork_sigchld_fn_t)(struct tevent_context *ev_ctx,
|
||||
/**
|
||||
* @brief Creates the first pool of preforked processes
|
||||
*
|
||||
* @param ev_ctx The event context
|
||||
* @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
|
||||
@ -108,7 +111,9 @@ typedef void (prefork_sigchld_fn_t)(struct tevent_context *ev_ctx,
|
||||
*
|
||||
* @return True if it was successful, False otherwise.
|
||||
*/
|
||||
bool prefork_create_pool(struct tevent_context *ev_ctx, TALLOC_CTX *mem_ctx,
|
||||
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,
|
||||
@ -132,6 +137,7 @@ 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
|
||||
*
|
||||
@ -141,6 +147,7 @@ int prefork_expand_pool(struct prefork_pool *pfp, int new_max);
|
||||
* 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);
|
||||
/**
|
||||
|
@ -357,13 +357,13 @@ struct spoolss_children_data {
|
||||
static void spoolss_next_client(void *pvt);
|
||||
|
||||
static int spoolss_children_main(struct tevent_context *ev_ctx,
|
||||
struct messaging_context *msg_ctx,
|
||||
struct pf_worker_data *pf,
|
||||
int listen_fd_size,
|
||||
int *listen_fds,
|
||||
int lock_fd,
|
||||
void *private_data)
|
||||
{
|
||||
struct messaging_context *msg_ctx = server_messaging_context();
|
||||
struct spoolss_children_data *data;
|
||||
bool ok;
|
||||
int ret;
|
||||
@ -538,6 +538,7 @@ static void check_updater_child(void)
|
||||
}
|
||||
|
||||
static bool spoolssd_schedule_check(struct tevent_context *ev_ctx,
|
||||
struct messaging_context *msg_ctx,
|
||||
struct prefork_pool *pfp,
|
||||
struct timeval current_time);
|
||||
static void spoolssd_check_children(struct tevent_context *ev_ctx,
|
||||
@ -547,11 +548,14 @@ static void spoolssd_check_children(struct tevent_context *ev_ctx,
|
||||
|
||||
static void spoolssd_sigchld_handler(struct tevent_context *ev_ctx,
|
||||
struct prefork_pool *pfp,
|
||||
void *private_data)
|
||||
void *pvt)
|
||||
{
|
||||
struct messaging_context *msg_ctx;
|
||||
int active, total;
|
||||
int n, r;
|
||||
|
||||
msg_ctx = talloc_get_type_abort(pvt, struct messaging_context);
|
||||
|
||||
/* now check we do not descend below the minimum */
|
||||
active = prefork_count_active_children(pfp, &total);
|
||||
|
||||
@ -563,7 +567,7 @@ static void spoolssd_sigchld_handler(struct tevent_context *ev_ctx,
|
||||
}
|
||||
|
||||
if (n > 0) {
|
||||
r = prefork_add_children(ev_ctx, pfp, n);
|
||||
r = prefork_add_children(ev_ctx, msg_ctx, pfp, n);
|
||||
if (r < n) {
|
||||
DEBUG(10, ("Tried to start %d children but only,"
|
||||
"%d were actually started.!\n", n, r));
|
||||
@ -575,35 +579,54 @@ static void spoolssd_sigchld_handler(struct tevent_context *ev_ctx,
|
||||
}
|
||||
|
||||
static bool spoolssd_setup_children_monitor(struct tevent_context *ev_ctx,
|
||||
struct messaging_context *msg_ctx,
|
||||
struct prefork_pool *pfp)
|
||||
{
|
||||
bool ok;
|
||||
|
||||
/* add our oun sigchld callback */
|
||||
prefork_set_sigchld_callback(pfp, spoolssd_sigchld_handler, NULL);
|
||||
prefork_set_sigchld_callback(pfp, spoolssd_sigchld_handler, msg_ctx);
|
||||
|
||||
ok = spoolssd_schedule_check(ev_ctx, pfp, tevent_timeval_current());
|
||||
ok = spoolssd_schedule_check(ev_ctx, msg_ctx, pfp,
|
||||
tevent_timeval_current());
|
||||
return ok;
|
||||
}
|
||||
|
||||
struct schedule_check_state {
|
||||
struct messaging_context *msg_ctx;
|
||||
struct prefork_pool *pfp;
|
||||
};
|
||||
|
||||
static bool spoolssd_schedule_check(struct tevent_context *ev_ctx,
|
||||
struct messaging_context *msg_ctx,
|
||||
struct prefork_pool *pfp,
|
||||
struct timeval current_time)
|
||||
{
|
||||
struct tevent_timer *te;
|
||||
struct timeval next_event;
|
||||
struct schedule_check_state *state;
|
||||
|
||||
/* check situation again in 10 seconds */
|
||||
next_event = tevent_timeval_current_ofs(10, 0);
|
||||
|
||||
state = talloc(ev_ctx, struct schedule_check_state);
|
||||
if (!state) {
|
||||
DEBUG(0, ("Out of memory!\n"));
|
||||
return false;
|
||||
}
|
||||
state->msg_ctx = msg_ctx;
|
||||
state->pfp = pfp;
|
||||
|
||||
/* TODO: check when the socket becomes readable, so that children
|
||||
* are checked only when there is some activity ? */
|
||||
te = tevent_add_timer(ev_ctx, pfp, next_event,
|
||||
spoolssd_check_children, pfp);
|
||||
spoolssd_check_children, state);
|
||||
if (!te) {
|
||||
DEBUG(2, ("Failed to set up children monitoring!\n"));
|
||||
talloc_free(state);
|
||||
return false;
|
||||
}
|
||||
talloc_steal(te, state);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -613,25 +636,26 @@ static void spoolssd_check_children(struct tevent_context *ev_ctx,
|
||||
struct timeval current_time,
|
||||
void *pvt)
|
||||
{
|
||||
struct prefork_pool *pfp;
|
||||
struct schedule_check_state *state;
|
||||
int active, total;
|
||||
int ret, n;
|
||||
|
||||
pfp = talloc_get_type_abort(pvt, struct prefork_pool);
|
||||
state = talloc_get_type_abort(pvt, struct schedule_check_state);
|
||||
|
||||
if ((spoolss_prefork_status & SPOOLSS_NEW_MAX) &&
|
||||
!(spoolss_prefork_status & SPOLLSS_ENOSPC)) {
|
||||
ret = prefork_expand_pool(pfp, spoolss_max_children);
|
||||
ret = prefork_expand_pool(state->pfp, spoolss_max_children);
|
||||
if (ret == ENOSPC) {
|
||||
spoolss_prefork_status |= SPOLLSS_ENOSPC;
|
||||
}
|
||||
spoolss_prefork_status &= ~SPOOLSS_NEW_MAX;
|
||||
}
|
||||
|
||||
active = prefork_count_active_children(pfp, &total);
|
||||
active = prefork_count_active_children(state->pfp, &total);
|
||||
|
||||
if (total - active < spoolss_spawn_rate) {
|
||||
n = prefork_add_children(ev_ctx, pfp, spoolss_spawn_rate);
|
||||
n = prefork_add_children(ev_ctx, state->msg_ctx,
|
||||
state->pfp, spoolss_spawn_rate);
|
||||
if (n < spoolss_spawn_rate) {
|
||||
DEBUG(10, ("Tried to start 5 children but only,"
|
||||
"%d were actually started.!\n", n));
|
||||
@ -640,12 +664,13 @@ static void spoolssd_check_children(struct tevent_context *ev_ctx,
|
||||
|
||||
if (total - active > spoolss_min_children) {
|
||||
if ((total - spoolss_min_children) >= spoolss_spawn_rate) {
|
||||
prefork_retire_children(pfp, spoolss_spawn_rate,
|
||||
prefork_retire_children(state->pfp, spoolss_spawn_rate,
|
||||
time(NULL) - SPOOLSS_MIN_LIFE);
|
||||
}
|
||||
}
|
||||
|
||||
ret = spoolssd_schedule_check(ev_ctx, pfp, current_time);
|
||||
ret = spoolssd_schedule_check(ev_ctx, state->msg_ctx,
|
||||
state->pfp, current_time);
|
||||
}
|
||||
|
||||
static void print_queue_forward(struct messaging_context *msg,
|
||||
@ -723,7 +748,9 @@ pid_t start_spoolssd(struct tevent_context *ev_ctx,
|
||||
|
||||
|
||||
/* start children before any more initialization is done */
|
||||
ok = prefork_create_pool(ev_ctx, ev_ctx, 1, &listen_fd,
|
||||
ok = prefork_create_pool(ev_ctx, /* mem_ctx */
|
||||
ev_ctx, msg_ctx,
|
||||
1, &listen_fd,
|
||||
spoolss_min_children,
|
||||
spoolss_max_children,
|
||||
&spoolss_children_main, NULL,
|
||||
@ -798,7 +825,7 @@ pid_t start_spoolssd(struct tevent_context *ev_ctx,
|
||||
|
||||
talloc_free(mem_ctx);
|
||||
|
||||
ok = spoolssd_setup_children_monitor(ev_ctx, pool);
|
||||
ok = spoolssd_setup_children_monitor(ev_ctx, msg_ctx, pool);
|
||||
if (!ok) {
|
||||
DEBUG(0, ("Failed to setup children monitoring!\n"));
|
||||
exit(1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user