Author: abartlet Date: 2006-08-10 10:03:42 +0000 (Thu, 10 Aug 2006) New Revision: 17475
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=17475 Log: When we make more than one remote search, we need to wait for them all to finish. Andrew Bartlett Modified: branches/SOC/mkhl/ldb-map/modules/ldb_map.c Changeset: Modified: branches/SOC/mkhl/ldb-map/modules/ldb_map.c =================================================================== --- branches/SOC/mkhl/ldb-map/modules/ldb_map.c 2006-08-10 01:51:27 UTC (rev 17474) +++ branches/SOC/mkhl/ldb-map/modules/ldb_map.c 2006-08-10 10:03:42 UTC (rev 17475) @@ -134,6 +134,10 @@ struct ldb_request *remote_req; struct ldb_request *down_req; struct ldb_request *search_req; + + /* for search, we may have a lot of contexts */ + int num_searches; + struct ldb_request **search_reqs; }; /* Context data for mapped search requests */ @@ -2073,6 +2077,7 @@ const struct ldb_dn *dn, const char * const *attrs, const struct ldb_parse_tree *tree, + void *context, ldb_search_callback callback) { struct ldb_request *req; @@ -2099,7 +2104,7 @@ } req->controls = NULL; - req->context = ac; + req->context = context; req->callback = callback; ldb_set_timeout_from_prev_req(ac->module->ldb, ac->orig_req, req); @@ -2129,7 +2134,7 @@ tree->operation = LDB_OP_PRESENT; tree->u.present.attr = talloc_strdup(tree, IS_MAPPED); - return map_search_base_req(ac, dn, attrs, tree, map_search_self_callback); + return map_search_base_req(ac, dn, attrs, tree, ac, map_search_self_callback); } /* Build a request to update the 'IS_MAPPED' attribute */ @@ -2325,13 +2330,23 @@ /* Prepare local search request */ /* TODO: use GUIDs here instead? */ - req = map_search_base_req(ac, ares->message->dn, NULL, NULL, map_local_merge_callback); + + ac->search_reqs = talloc_realloc(ac, ac->search_reqs, struct ldb_request *, ac->num_searches + 2); + if (ac->search_reqs == NULL) { + talloc_free(ares); + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->search_reqs[ac->num_searches] + = req = map_search_base_req(ac, ares->message->dn, + NULL, NULL, sc, map_local_merge_callback); if (req == NULL) { talloc_free(sc); talloc_free(ares); return LDB_ERR_OPERATIONS_ERROR; } - req->context = sc; + ac->num_searches++; + ac->search_reqs[ac->num_searches] = NULL; return ldb_next_request(ac->module, req); } @@ -2367,30 +2382,38 @@ } ac = talloc_get_type(h->private_data, struct map_context); + ac->search_reqs = talloc_array(ac, struct ldb_request *, 2); + if (ac->search_reqs == NULL) { + talloc_free(h); + return LDB_ERR_OPERATIONS_ERROR; + } + ac->num_searches = 1; + ac->search_reqs[1] = NULL; + /* Prepare the remote operation */ - ac->remote_req = talloc(ac, struct ldb_request); - if (ac->remote_req == NULL) { + ac->search_reqs[0] = talloc(ac, struct ldb_request); + if (ac->search_reqs[0] == NULL) { goto oom; } - *(ac->remote_req) = *req; /* copy the request */ + *(ac->search_reqs[0]) = *req; /* copy the request */ - ac->remote_req->handle = h; /* return our own handle to deal with this call */ + ac->search_reqs[0]->handle = h; /* return our own handle to deal with this call */ - ac->remote_req->context = ac; - ac->remote_req->callback = map_remote_search_callback; + ac->search_reqs[0]->context = ac; + ac->search_reqs[0]->callback = map_remote_search_callback; /* Split local from remote attrs */ - ret = map_flarp(module, ac, ac->remote_req, &local_attrs, &remote_attrs, req->op.search.attrs, req->op.search.tree); + ret = map_flarp(module, ac, ac->search_reqs[0], &local_attrs, &remote_attrs, req->op.search.attrs, req->op.search.tree); if (ret) { goto failed; } ac->local_attrs = local_attrs; - ac->remote_req->op.search.attrs = remote_attrs; + ac->search_reqs[0]->op.search.attrs = remote_attrs; /* Split local from remote tree */ - ret = ldb_parse_tree_partition(module, ac, ac->remote_req, &local_tree, &remote_tree, req->op.search.tree); + ret = ldb_parse_tree_partition(module, ac, ac->search_reqs[0], &local_tree, &remote_tree, req->op.search.tree); if (ret) { goto failed; } @@ -2415,25 +2438,25 @@ } if (remote_tree == NULL) { /* Construct default remote parse tree */ - remote_tree = ldb_parse_tree(ac->remote_req, NULL); + remote_tree = ldb_parse_tree(ac->search_reqs[0], NULL); if (remote_tree == NULL) { goto failed; } } ac->local_tree = local_tree; - ac->remote_req->op.search.tree = remote_tree; + ac->search_reqs[0]->op.search.tree = remote_tree; - ldb_set_timeout_from_prev_req(module->ldb, req, ac->remote_req); + ldb_set_timeout_from_prev_req(module->ldb, req, ac->search_reqs[0]); h->state = LDB_ASYNC_INIT; h->status = LDB_SUCCESS; ac->step = MAP_SEARCH_REMOTE; - ret = ldb_next_remote_request(module, ac->remote_req); + ret = ldb_next_remote_request(module, ac->search_reqs[0]); if (ret == LDB_SUCCESS) { - req->handle = ac->remote_req->handle; + req->handle = h; } return ret; @@ -3046,12 +3069,15 @@ case MAP_RENAME_FIXUP: return ac->down_req; - case MAP_SEARCH_REMOTE: case MAP_ADD_LOCAL: case MAP_MODIFY_LOCAL: case MAP_DELETE_LOCAL: case MAP_RENAME_LOCAL: return ac->local_req; + + case MAP_SEARCH_REMOTE: + /* Can't happen */ + break; } return NULL; /* unreachable; silences a warning */ @@ -3123,27 +3149,48 @@ ac = talloc_get_type(handle->private_data, struct map_context); - req = map_get_req(ac); - - ret = ldb_wait(req->handle, LDB_WAIT_NONE); - - if (ret != LDB_SUCCESS) { - handle->status = ret; - goto done; - } - if (req->handle->status != LDB_SUCCESS) { + if (ac->step == MAP_SEARCH_REMOTE) { + int i; + for (i=0; i < ac->num_searches; i++) { + req = ac->search_reqs[i]; + ret = ldb_wait(req->handle, LDB_WAIT_NONE); + + if (ret != LDB_SUCCESS) { + handle->status = ret; + goto done; + } + if (req->handle->status != LDB_SUCCESS) { + handle->status = req->handle->status; + goto done; + } + if (req->handle->state != LDB_ASYNC_DONE) { + return LDB_SUCCESS; + } + } + } else { + + req = map_get_req(ac); + + ret = ldb_wait(req->handle, LDB_WAIT_NONE); + + if (ret != LDB_SUCCESS) { + handle->status = ret; + goto done; + } + if (req->handle->status != LDB_SUCCESS) { handle->status = req->handle->status; goto done; + } + if (req->handle->state != LDB_ASYNC_DONE) { + return LDB_SUCCESS; + } + + next = map_get_next(ac); + if (next) { + return next(handle); + } } - if (req->handle->state != LDB_ASYNC_DONE) { - return LDB_SUCCESS; - } - next = map_get_next(ac); - if (next) { - return next(handle); - } - ret = LDB_SUCCESS; done: