s3-prefork: add way to manage number of clients per child
authorSimo Sorce <idra@samba.org>
Thu, 5 May 2011 21:56:31 +0000 (17:56 -0400)
committerAndreas Schneider <asn@samba.org>
Wed, 10 Aug 2011 16:14:03 +0000 (18:14 +0200)
The allowed_clients var is a parent managed variable that tell children how
many clients they are allowed to handle at the same time. This way children
can overcommit but within parent controlled limits.

Signed-off-by: Andreas Schneider <asn@samba.org>
source3/lib/server_prefork.c
source3/lib/server_prefork.h

index b337fa0c3b4ef0dfe2495ee5df937e951805788d..0a8199a6ea47bffa3020fd927ec46216bc88bdb5 100644 (file)
@@ -36,6 +36,8 @@ struct prefork_pool {
 
        int pool_size;
        struct pf_worker_data *pool;
+
+       int allowed_clients;
 };
 
 int prefork_pool_destructor(struct prefork_pool *pfp)
@@ -86,6 +88,10 @@ bool prefork_create_pool(struct tevent_context *ev_ctx,
        talloc_set_destructor(pfp, prefork_pool_destructor);
 
        for (i = 0; i < min_children; i++) {
+
+               pfp->pool[i].allowed_clients = 1;
+               pfp->pool[i].started = now;
+
                pid = sys_fork();
                switch (pid) {
                case -1:
@@ -102,7 +108,6 @@ bool prefork_create_pool(struct tevent_context *ev_ctx,
 
                default: /* THE PARENT */
                        pfp->pool[i].pid = pid;
-                       pfp->pool[i].started = now;
                        break;
                }
        }
@@ -126,6 +131,9 @@ int prefork_add_children(struct tevent_context *ev_ctx,
                        continue;
                }
 
+               pfp->pool[i].allowed_clients = 1;
+               pfp->pool[i].started = now;
+
                pid = sys_fork();
                switch (pid) {
                case -1:
@@ -144,7 +152,6 @@ int prefork_add_children(struct tevent_context *ev_ctx,
 
                default: /* THE PARENT */
                        pfp->pool[i].pid = pid;
-                       pfp->pool[i].started = now;
                        j++;
                        break;
                }
@@ -263,6 +270,30 @@ bool prefork_mark_pid_dead(struct prefork_pool *pfp, pid_t pid)
        return false;
 }
 
+void prefork_increase_allowed_clients(struct prefork_pool *pfp, int max)
+{
+       int i;
+
+       for (i = 0; i < pfp->pool_size; i++) {
+               if (pfp->pool[i].status == PF_WORKER_NONE) {
+                       continue;
+               }
+
+               if (pfp->pool[i].allowed_clients < max) {
+                       pfp->pool[i].allowed_clients++;
+               }
+       }
+}
+
+void prefork_reset_allowed_clients(struct prefork_pool *pfp)
+{
+       int i;
+
+       for (i = 0; i < pfp->pool_size; i++) {
+               pfp->pool[i].allowed_clients = 1;
+       }
+}
+
 /* ==== Functions used by children ==== */
 
 static SIG_ATOMIC_T pf_alarm;
index 7e95602e814a26bddd28f7f7084ba09f7d2148ff..bf9f3d3fe7460ec30d695c40297289bb979e0693 100644 (file)
@@ -37,10 +37,12 @@ enum pf_server_cmds {
 struct pf_worker_data {
        pid_t pid;
        enum pf_worker_status status;
-       enum pf_server_cmds cmds;
        time_t started;
        time_t last_used;
        int num_clients;
+
+       enum pf_server_cmds cmds;
+       int allowed_clients;
 };
 
 typedef int (prefork_main_fn_t)(struct tevent_context *ev,
@@ -67,6 +69,8 @@ int prefork_retire_children(struct prefork_pool *pfp,
                            int num_children, time_t age_limit);
 int prefork_count_active_children(struct prefork_pool *pfp, int *total);
 bool prefork_mark_pid_dead(struct prefork_pool *pfp, pid_t pid);
+void prefork_increase_allowed_clients(struct prefork_pool *pfp, int max);
+void prefork_reset_allowed_clients(struct prefork_pool *pfp);
 
 /* ==== Functions used by children ==== */