summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2011-08-12 12:24:48 -0400
committerSimo Sorce <idra@samba.org>2011-08-21 09:05:04 -0400
commit0647a93c64ce5d87527d6c9e34688f93e7cd03b3 (patch)
tree33404b51a1f3e310f3a0092a00687bf18c92ce63
parent2a0aac0adcdccc165f5d511d7a1c1d6d0c5d7c9b (diff)
downloadsamba-0647a93c64ce5d87527d6c9e34688f93e7cd03b3.tar.gz
samba-0647a93c64ce5d87527d6c9e34688f93e7cd03b3.tar.bz2
samba-0647a93c64ce5d87527d6c9e34688f93e7cd03b3.zip
s3-spoolss: Introduce helper function to manage pool.
We were not properly managing allowed clients and pool management was duplicated across a few callers. Concentrate all management heuristics in one single function. Signed-off-by: Andreas Schneider <asn@samba.org> Signed-off-by: Simo Sorce <idra@samba.org>
-rw-r--r--source3/printing/spoolssd.c116
1 files changed, 64 insertions, 52 deletions
diff --git a/source3/printing/spoolssd.c b/source3/printing/spoolssd.c
index bc4065c04e..2cbd6e3603 100644
--- a/source3/printing/spoolssd.c
+++ b/source3/printing/spoolssd.c
@@ -56,6 +56,8 @@ static int spoolss_child_id = 0;
pid_t start_spoolssd(struct tevent_context *ev_ctx,
struct messaging_context *msg_ctx);
+static void spoolss_manage_pool(struct tevent_context *ev_ctx,
+ struct messaging_context *msg_ctx);
static void spoolss_prefork_config(void)
{
@@ -75,13 +77,13 @@ static void spoolss_prefork_config(void)
}
prefork_str = lp_parm_const_string(GLOBAL_SECTION_SNUM,
- "spoolssd", "prefork", "none");
+ "spoolss", "prefork", "none");
if (strcmp(prefork_str, "none") == 0) {
use_defaults = true;
} else {
ret = sscanf(prefork_str, "%d:%d:%d", &min, &max, &rate);
if (ret != 3) {
- DEBUG(0, ("invalid format for spoolssd:prefork!\n"));
+ DEBUG(0, ("invalid format for spoolss:prefork!\n"));
use_defaults = true;
}
}
@@ -153,6 +155,7 @@ static void update_conf(struct tevent_context *ev,
spoolss_reopen_logs(spoolss_child_id);
if (spoolss_child_id == 0) {
spoolss_prefork_config();
+ spoolss_manage_pool(ev, msg);
}
}
@@ -585,6 +588,58 @@ static void check_updater_child(void)
}
}
+static void spoolss_manage_pool(struct tevent_context *ev_ctx,
+ struct messaging_context *msg_ctx)
+{
+ time_t now = time(NULL);
+ int active, total;
+ int ret, n;
+
+ if ((spoolss_prefork_status & SPOOLSS_NEW_MAX) &&
+ !(spoolss_prefork_status & SPOLLSS_ENOSPC)) {
+ ret = prefork_expand_pool(spoolss_pool, spoolss_max_children);
+ if (ret == ENOSPC) {
+ spoolss_prefork_status |= SPOLLSS_ENOSPC;
+ }
+ spoolss_prefork_status &= ~SPOOLSS_NEW_MAX;
+ }
+
+ active = prefork_count_active_children(spoolss_pool, &total);
+
+ if ((total < spoolss_max_children) &&
+ ((total < spoolss_min_children) ||
+ (total - active < spoolss_spawn_rate))) {
+ n = prefork_add_children(ev_ctx, msg_ctx,
+ spoolss_pool, spoolss_spawn_rate);
+ if (n < spoolss_spawn_rate) {
+ DEBUG(10, ("Tried to start %d children but only,"
+ "%d were actually started.!\n",
+ spoolss_spawn_rate, n));
+ }
+ }
+
+ if (total - active > spoolss_min_children) {
+ if ((total - spoolss_min_children) >= spoolss_spawn_rate) {
+ prefork_retire_children(spoolss_pool,
+ spoolss_spawn_rate,
+ now - SPOOLSS_MIN_LIFE);
+ }
+ }
+
+ n = prefork_count_allowed_connections(spoolss_pool);
+ if (n <= spoolss_spawn_rate) {
+ do {
+ prefork_increase_allowed_clients(spoolss_pool);
+ n = prefork_count_allowed_connections(spoolss_pool);
+ } while (n <= spoolss_spawn_rate);
+ } else if (n > spoolss_max_children + spoolss_spawn_rate) {
+ do {
+ prefork_decrease_allowed_clients(spoolss_pool);
+ n = prefork_count_allowed_connections(spoolss_pool);
+ } while (n > spoolss_max_children + spoolss_spawn_rate);
+ }
+}
+
static bool spoolssd_schedule_check(struct tevent_context *ev_ctx,
struct messaging_context *msg_ctx,
struct timeval current_time);
@@ -598,28 +653,12 @@ static void spoolssd_sigchld_handler(struct tevent_context *ev_ctx,
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);
-
- n = 0;
- if (total < spoolss_min_children) {
- n = total - spoolss_min_children;
- } else if (total - active < (total / 4)) {
- n = spoolss_min_children;
- }
-
- if (n > 0) {
- 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));
- }
- }
+ /* run pool management so we can fork/retire or increase
+ * the allowed connections per child based on load */
+ spoolss_manage_pool(ev_ctx, msg_ctx);
/* also check if the updater child is alive and well */
check_updater_child();
@@ -667,41 +706,12 @@ static void spoolssd_check_children(struct tevent_context *ev_ctx,
void *pvt)
{
struct messaging_context *msg_ctx;
- time_t now = time(NULL);
- int active, total;
- int ret, n;
msg_ctx = talloc_get_type_abort(pvt, struct messaging_context);
- if ((spoolss_prefork_status & SPOOLSS_NEW_MAX) &&
- !(spoolss_prefork_status & SPOLLSS_ENOSPC)) {
- ret = prefork_expand_pool(spoolss_pool, spoolss_max_children);
- if (ret == ENOSPC) {
- spoolss_prefork_status |= SPOLLSS_ENOSPC;
- }
- spoolss_prefork_status &= ~SPOOLSS_NEW_MAX;
- }
-
- active = prefork_count_active_children(spoolss_pool, &total);
+ spoolss_manage_pool(ev_ctx, msg_ctx);
- if (total - active < spoolss_spawn_rate) {
- n = prefork_add_children(ev_ctx, msg_ctx,
- spoolss_pool, spoolss_spawn_rate);
- if (n < spoolss_spawn_rate) {
- DEBUG(10, ("Tried to start 5 children but only,"
- "%d were actually started.!\n", n));
- }
- }
-
- if (total - active > spoolss_min_children) {
- if ((total - spoolss_min_children) >= spoolss_spawn_rate) {
- prefork_retire_children(spoolss_pool,
- spoolss_spawn_rate,
- now - SPOOLSS_MIN_LIFE);
- }
- }
-
- ret = spoolssd_schedule_check(ev_ctx, msg_ctx, current_time);
+ spoolssd_schedule_check(ev_ctx, msg_ctx, current_time);
}
static void print_queue_forward(struct messaging_context *msg,
@@ -906,6 +916,8 @@ pid_t start_spoolssd(struct tevent_context *ev_ctx,
DEBUG(1, ("SPOOLSS Daemon Started (%d)\n", getpid()));
+ spoolss_manage_pool(ev_ctx, msg_ctx);
+
/* loop forever */
ret = tevent_loop_wait(ev_ctx);