s3: Fork multiple children per domain
authorVolker Lendecke <vl@samba.org>
Wed, 7 Apr 2010 15:45:12 +0000 (17:45 +0200)
committerVolker Lendecke <vl@samba.org>
Wed, 14 Apr 2010 14:39:57 +0000 (16:39 +0200)
source/param/loadparm.c
source/winbindd/winbindd.h
source/winbindd/winbindd_domain.c
source/winbindd/winbindd_dual.c
source/winbindd/winbindd_ndr.c
source/winbindd/winbindd_util.c

index ddb7181e9b28d04f0a22dc4660bcaf1a3d805a8f..1cd263477b64ff94a9fad473ffe0fc69a923a5d2 100644 (file)
@@ -196,6 +196,7 @@ struct global {
        bool bWinbindNormalizeNames;
        bool bWinbindRpcOnly;
        bool bCreateKrb5Conf;
+       int winbindMaxDomainConnections;
        char *szIdmapBackend;
        char *szIdmapAllocBackend;
        char *szAddShareCommand;
@@ -4455,6 +4456,15 @@ static struct parm_struct parm_table[] = {
                .enum_list      = NULL,
                .flags          = FLAG_ADVANCED,
        },
+       {
+               .label          = "winbind max domain connections",
+               .type           = P_INTEGER,
+               .p_class        = P_GLOBAL,
+               .ptr            = &Globals.winbindMaxDomainConnections,
+               .special        = NULL,
+               .enum_list      = NULL,
+               .flags          = FLAG_ADVANCED,
+       },
 
        {NULL,  P_BOOL,  P_NONE,  NULL,  NULL,  NULL,  0}
 };
@@ -4751,6 +4761,7 @@ static void init_globals(bool first_time_only)
        Globals.bUnixExtensions = True;
        Globals.bResetOnZeroVC = False;
        Globals.bCreateKrb5Conf = true;
+       Globals.winbindMaxDomainConnections = 2;
 
        /* hostname lookups can be very expensive and are broken on
           a large number of sites (tridge) */
@@ -5073,6 +5084,8 @@ FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
 FN_GLOBAL_BOOL(lp_create_krb5_conf, &Globals.bCreateKrb5Conf)
+FN_GLOBAL_INTEGER(lp_winbind_max_domain_connections,
+                 &Globals.winbindMaxDomainConnections)
 
 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
index 79d0a7c3371eb2e3ac5806c3c113dea799184588..07033379bfac240972129b86296c6ee6072b5ba0 100644 (file)
@@ -218,7 +218,7 @@ struct winbindd_domain {
 
        /* The child pid we're talking to */
 
-       struct winbindd_child child;
+       struct winbindd_child *children;
 
        /* Callback we use to try put us back online. */
 
index 23b2bbdddb7e8eecf1dd1ae36f5787b18f7c079a..08182a3b6824dc9080ddabc543fcbcadc9b65a11 100644 (file)
@@ -29,10 +29,13 @@ static const struct winbindd_child_dispatch_table domain_dispatch_table[];
 
 void setup_domain_child(struct winbindd_domain *domain)
 {
-       setup_child(&domain->child, domain_dispatch_table,
-                   "log.wb", domain->name);
+       int i;
 
-       domain->child.domain = domain;
+       for (i=0; i<lp_winbind_max_domain_connections(); i++) {
+               setup_child(&domain->children[i], domain_dispatch_table,
+                           "log.wb", domain->name);
+               domain->children[i].domain = domain;
+       }
 }
 
 static const struct winbindd_child_dispatch_table domain_dispatch_table[] = {
index 74582888149a4d7e19aa964ed5349391606e4983..e8b9b51fb44bf3f9521ea53e3532c14a03037664 100644 (file)
@@ -341,6 +341,31 @@ static void schedule_async_request(struct winbindd_child *child)
        return;
 }
 
+static struct winbindd_child *find_idle_child(struct winbindd_domain *domain)
+{
+       int i;
+
+       for (i=0; i<lp_winbind_max_domain_connections(); i++) {
+               if (!winbindd_child_busy(&domain->children[i])) {
+                       return &domain->children[i];
+               }
+       }
+
+       return NULL;
+}
+
+static struct winbindd_child *choose_domain_child(
+       struct winbindd_domain *domain)
+{
+       struct winbindd_child *result;
+
+       result = find_idle_child(domain);
+       if (result != NULL) {
+               return result;
+       }
+       return &domain->children[rand() % lp_winbind_max_domain_connections()];
+}
+
 struct domain_request_state {
        TALLOC_CTX *mem_ctx;
        struct winbindd_domain *domain;
@@ -362,7 +387,9 @@ void async_domain_request(TALLOC_CTX *mem_ctx,
        struct domain_request_state *state;
 
        if (domain->initialized) {
-               async_request(mem_ctx, &domain->child, request, response,
+               struct winbindd_child *child = choose_domain_child(domain);
+
+               async_request(mem_ctx, child, request, response,
                              continuation, private_data_data);
                return;
        }
@@ -395,7 +422,7 @@ static void domain_init_recv(void *private_data_data, bool success)
                return;
        }
 
-       async_request(state->mem_ctx, &state->domain->child,
+       async_request(state->mem_ctx, &state->domain->children[0],
                      state->request, state->response,
                      state->continuation, state->private_data_data);
 }
index 3e3ca3225c6d78e053fd9b84e4962637e55f8c2c..26bc3cb527a6c00a5c5c022df2b50af504969696 100644 (file)
@@ -119,6 +119,7 @@ void ndr_print_winbindd_domain(struct ndr_print *ndr,
                               const char *name,
                               const struct winbindd_domain *r)
 {
+       int i;
        if (!r) {
                return;
        }
@@ -149,7 +150,9 @@ void ndr_print_winbindd_domain(struct ndr_print *ndr,
        ndr_print_uint32(ndr, "sequence_number", r->sequence_number);
        ndr_print_NTSTATUS(ndr, "last_status", r->last_status);
        ndr_print_winbindd_cm_conn(ndr, "conn", &r->conn);
-       ndr_print_winbindd_child(ndr, "child", &r->child);
+       for (i=0; i<lp_winbind_max_domain_connections(); i++) {
+               ndr_print_winbindd_child(ndr, "children", &r->children[i]);
+       }
        ndr_print_uint32(ndr, "check_online_timeout", r->check_online_timeout);
        ndr_print_ptr(ndr, "check_online_event", r->check_online_event);
        ndr->depth--;
index dae1707393517384b486bdcd178663d727670be2..32af572b2255ce90b70e2c5268777111121ac97a 100644 (file)
@@ -176,6 +176,16 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
         
        ZERO_STRUCTP(domain);
 
+       domain->children = SMB_MALLOC_ARRAY(
+               struct winbindd_child, lp_winbind_max_domain_connections());
+       if (domain->children == NULL) {
+               SAFE_FREE(domain);
+               return NULL;
+       }
+       memset(domain->children, 0,
+              sizeof(struct winbindd_child)
+              * lp_winbind_max_domain_connections());
+
        fstrcpy(domain->name, domain_name);
        if (alternative_name) {
                fstrcpy(domain->alt_name, alternative_name);
@@ -623,7 +633,7 @@ enum winbindd_result init_child_connection(struct winbindd_domain *domain,
                fstrcpy(request->domain_name, domain->name);
                request->data.init_conn.is_primary = domain->primary ? true : false;
                fstrcpy(request->data.init_conn.dcname, "");
-               async_request(mem_ctx, &domain->child, request, response,
+               async_request(mem_ctx, &domain->children[0], request, response,
                              init_child_recv, state);
                return WINBINDD_PENDING;
        }
@@ -657,7 +667,7 @@ static void init_child_getdc_recv(void *private_data, bool success)
        state->request->data.init_conn.is_primary = False;
        fstrcpy(state->request->data.init_conn.dcname, dcname);
 
-       async_request(state->mem_ctx, &state->domain->child,
+       async_request(state->mem_ctx, &state->domain->children[0],
                      state->request, state->response,
                      init_child_recv, state);
 }