From 3451f423d6a70da054c06135bc36daf0677b53f9 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 12 Aug 2011 15:24:17 -0400 Subject: s3-prefork: Add common utilities for daemons Daemons using the prefork infrastructure may want to use these utils to configure and manage a pool of children. Signed-off-by: Andreas Schneider Signed-off-by: Simo Sorce --- source3/Makefile.in | 1 + source3/lib/server_prefork_util.c | 117 ++++++++++++++++++++++++++++++++++++++ source3/lib/server_prefork_util.h | 49 ++++++++++++++++ source3/wscript_build | 1 + 4 files changed, 168 insertions(+) create mode 100644 source3/lib/server_prefork_util.c create mode 100644 source3/lib/server_prefork_util.h diff --git a/source3/Makefile.in b/source3/Makefile.in index 0332508d02..4937f3003e 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -466,6 +466,7 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) $(LIBTSOCKET_OBJ) \ @CCAN_OBJ@ \ lib/server_contexts.o \ lib/server_prefork.o \ + lib/server_prefork_util.o \ lib/ldap_escape.o @CHARSET_STATIC@ \ ../libcli/security/secdesc.o ../libcli/security/access_check.o \ ../libcli/security/secace.o ../libcli/security/object_tree.o \ diff --git a/source3/lib/server_prefork_util.c b/source3/lib/server_prefork_util.c new file mode 100644 index 0000000000..6b1e249335 --- /dev/null +++ b/source3/lib/server_prefork_util.c @@ -0,0 +1,117 @@ +/* + Unix SMB/Netbios implementation. + Prefork Helpers + Copyright (C) Simo Sorce 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 . +*/ + +#include "includes.h" +#include "lib/server_prefork.h" +#include "lib/server_prefork_util.h" + +void pfh_daemon_config(const char *daemon_name, + struct pf_daemon_config *cfg, + struct pf_daemon_config *default_cfg) +{ + int min, max, rate, allow, life; + + min = lp_parm_int(GLOBAL_SECTION_SNUM, + daemon_name, + "prefork_min_children", + default_cfg->min_children); + max = lp_parm_int(GLOBAL_SECTION_SNUM, + daemon_name, + "prefork_max_children", + default_cfg->max_children); + rate = lp_parm_int(GLOBAL_SECTION_SNUM, + daemon_name, + "prefork_spawn_rate", + default_cfg->spawn_rate); + allow = lp_parm_int(GLOBAL_SECTION_SNUM, + daemon_name, + "prefork_max_allowed_clients", + default_cfg->max_allowed_clients); + life = lp_parm_int(GLOBAL_SECTION_SNUM, + daemon_name, + "prefork_child_min_life", + default_cfg->child_min_life); + + if (max > cfg->max_children && cfg->max_children != 0) { + cfg->prefork_status |= PFH_NEW_MAX; + } + + cfg->min_children = min; + cfg->max_children = max; + cfg->spawn_rate = rate; + cfg->max_allowed_clients = allow; + cfg->child_min_life = life; +} + +void pfh_manage_pool(struct tevent_context *ev_ctx, + struct messaging_context *msg_ctx, + struct pf_daemon_config *cfg, + struct prefork_pool *pool) +{ + time_t now = time(NULL); + int active, total; + int ret, n; + + if ((cfg->prefork_status & PFH_NEW_MAX) && + !(cfg->prefork_status & PFH_ENOSPC)) { + ret = prefork_expand_pool(pool, cfg->max_children); + if (ret == ENOSPC) { + cfg->prefork_status |= PFH_ENOSPC; + } + cfg->prefork_status &= ~PFH_NEW_MAX; + } + + active = prefork_count_active_children(pool, &total); + + if ((total < cfg->max_children) && + ((total < cfg->min_children) || + (total - active < cfg->spawn_rate))) { + n = prefork_add_children(ev_ctx, msg_ctx, + pool, cfg->spawn_rate); + if (n < cfg->spawn_rate) { + DEBUG(10, ("Tried to start %d children but only," + "%d were actually started.!\n", + cfg->spawn_rate, n)); + } + } + + if (total - active > cfg->min_children) { + if ((total - cfg->min_children) >= cfg->spawn_rate) { + prefork_retire_children(pool, cfg->spawn_rate, + now - cfg->child_min_life); + } + } + + n = prefork_count_allowed_connections(pool); + if (n <= cfg->spawn_rate) { + do { + prefork_increase_allowed_clients(pool, + cfg->max_allowed_clients); + n = prefork_count_allowed_connections(pool); + } while (n <= cfg->spawn_rate); + } else if (n > cfg->max_children + cfg->spawn_rate) { + do { + prefork_decrease_allowed_clients(pool); + n = prefork_count_allowed_connections(pool); + } while (n > cfg->max_children + cfg->spawn_rate); + } + + DEBUG(10, ("Stats: children: %d, allowed connections: %d\n", + total, prefork_count_allowed_connections(pool))); +} diff --git a/source3/lib/server_prefork_util.h b/source3/lib/server_prefork_util.h new file mode 100644 index 0000000000..5715f06f4a --- /dev/null +++ b/source3/lib/server_prefork_util.h @@ -0,0 +1,49 @@ +/* + Unix SMB/CIFS implementation. + Prefork Helpers. + + Copyright (C) Simo Sorce 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 . +*/ + +#ifndef _SERVER_PREFORK_UTIL_H_ +#define _SERVER_PREFORK_UTIL_H_ + +struct tevent_context; +struct messaging_context; + +#define PFH_INIT 0x00 +#define PFH_NEW_MAX 0x01 +#define PFH_ENOSPC 0x02 + +struct pf_daemon_config { + int prefork_status; + int min_children; + int max_children; + int spawn_rate; + int max_allowed_clients; + int child_min_life; +}; + +void pfh_daemon_config(const char *daemon_name, + struct pf_daemon_config *cfg, + struct pf_daemon_config *default_cfg); + +void pfh_manage_pool(struct tevent_context *ev_ctx, + struct messaging_context *msg_ctx, + struct pf_daemon_config *cfg, + struct prefork_pool *pool); + +#endif /* _SERVER_PREFORK_UTIL_H_ */ diff --git a/source3/wscript_build b/source3/wscript_build index 8d4a02f33a..5a91e0421f 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -82,6 +82,7 @@ LIB_SRC = ''' lib/module.c lib/events.c lib/server_contexts.c lib/server_prefork.c + lib/server_prefork_util.c lib/ldap_escape.c lib/fncall.c libads/krb5_errs.c lib/system_smbd.c lib/audit.c -- cgit