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>
Thu, 8 Apr 2010 14:33:59 +0000 (16:33 +0200)
source3/include/proto.h
source3/param/loadparm.c
source3/winbindd/winbindd.h
source3/winbindd/winbindd_domain.c
source3/winbindd/winbindd_dual.c
source3/winbindd/winbindd_ndr.c
source3/winbindd/winbindd_util.c

index 47b56def86f4efb75bc2e248a41ba98b2fb7848d..1802558fbcfcfe9fdb72c82b3d48cac55060b23d 100644 (file)
@@ -3993,6 +3993,7 @@ bool lp_winbind_offline_logon(void);
 bool lp_winbind_normalize_names(void);
 bool lp_winbind_rpc_only(void);
 bool lp_create_krb5_conf(void);
+int lp_winbind_max_domain_connections(void);
 const char **lp_idmap_domains(void);
 const char *lp_idmap_backend(void);
 char *lp_idmap_alloc_backend(void);
index e18936123ceb5d5481b8009b0633024da9ec8b64..5eadcaf3c52307e8ced0f427b10871a913bafede 100644 (file)
@@ -200,6 +200,7 @@ struct global {
        bool bWinbindNormalizeNames;
        bool bWinbindRpcOnly;
        bool bCreateKrb5Conf;
+       int winbindMaxDomainConnections;
        char *szIdmapBackend;
        char *szIdmapAllocBackend;
        char *szAddShareCommand;
@@ -4617,6 +4618,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}
 };
@@ -5052,6 +5062,7 @@ static void init_globals(bool first_time_only)
        Globals.bResetOnZeroVC = False;
        Globals.bLogWriteableFilesOnExit = False;
        Globals.bCreateKrb5Conf = true;
+       Globals.winbindMaxDomainConnections = 2;
 
        /* hostname lookups can be very expensive and are broken on
           a large number of sites (tridge) */
@@ -5406,6 +5417,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 16812d82a9eb5610bd63acbd3e367234d6f03353..b697daeaa0c9e8547a85c9511448743488ec4cab 100644 (file)
@@ -220,7 +220,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 0f0de9cc5ce2b9758eaa1a619e7db1c395075ecd..8bedfce04a986354d98c67c4f3c5c5d9c9037f5d 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 ad8cdd2cd0cb38bee6295bc9d62eefcd08e5be65..a5ba9e0116cf6e6a6ac1b56522cd4ad0b5ba7532 100644 (file)
@@ -340,6 +340,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;
@@ -361,7 +386,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;
        }
@@ -394,7 +421,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 389c9de16f8f463396a43de890495c8c937b9b53..c79237c9190dee99058ee970e4135759c69912b7 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);
 }