s3-prefork: Add common utilities for daemons
authorSimo Sorce <idra@samba.org>
Fri, 12 Aug 2011 19:24:17 +0000 (15:24 -0400)
committerSimo Sorce <idra@samba.org>
Sun, 21 Aug 2011 13:05:04 +0000 (09:05 -0400)
Daemons using the prefork infrastructure may want to use these utils to
configure and manage a pool of children.

Signed-off-by: Andreas Schneider <asn@samba.org>
Signed-off-by: Simo Sorce <idra@samba.org>
source3/Makefile.in
source3/lib/server_prefork_util.c [new file with mode: 0644]
source3/lib/server_prefork_util.h [new file with mode: 0644]
source3/wscript_build

index 0332508d027bd460d59bdcaa653cdc64297f77da..4937f3003ec23ecd946f60052240a5334ae358d0 100644 (file)
@@ -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 (file)
index 0000000..6b1e249
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+   Unix SMB/Netbios implementation.
+   Prefork Helpers
+   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 "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 (file)
index 0000000..5715f06
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+   Unix SMB/CIFS implementation.
+   Prefork Helpers.
+
+   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/>.
+*/
+
+#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_ */
index 8d4a02f33a9aab549b4f4243240b2309b98fb1ce..5a91e0421f0e37af70378af43a7f70345567c355 100755 (executable)
@@ -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