From a05c1c6fd6e2b93e411702674afa8b45c6e8ca30 Mon Sep 17 00:00:00 2001
From: Noriko Hosoi <nhosoi@redhat.com>
Date: Sat, 30 May 2015 16:44:14 -0700
Subject: [PATCH 328/329] Ticket #48146 - async simple paged results issue
Description: commit 5e9c4f1f09596dd076a6c3a0bb419580e8fd705e broke the
CI test case ticket47824_test.py.
If the simple paged results search is operated on a backend having one
or more sub-backends underneath, it fails to pick up the next sub-back
ends, but repeats the search on the parent backend. The problem was
fixed.
https://fedorahosted.org/389/ticket/48146
Reviewed by mreynolds@redhat.com (Thank you, Mark!!)
(cherry picked from commit 03d3455dfbe84f034a234df2ebd8cfdd7ad15f48)
(cherry picked from commit f6fe5bfe4c1fb1402af789a0f935c765c299d103)
(cherry picked from commit 64b54d416e75eaeb611ece982c1be9acf3f56161)
(cherry picked from commit b50095835b1889f8578ea3da579b543ed1619885)
---
ldap/servers/slapd/opshared.c | 87 ++++++++++++++++++++-----------------------
1 file changed, 41 insertions(+), 46 deletions(-)
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
index bfacb9e..d446f50 100644
--- a/ldap/servers/slapd/opshared.c
+++ b/ldap/servers/slapd/opshared.c
@@ -463,46 +463,31 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
}
}
- if (be_name == NULL)
- {
- /* no specific backend was requested, use the mapping tree
- */
- err_code = slapi_mapping_tree_select_all(pb, be_list, referral_list, errorbuf);
- if (((err_code != LDAP_SUCCESS) && (err_code != LDAP_OPERATIONS_ERROR) && (err_code != LDAP_REFERRAL))
- || ((err_code == LDAP_OPERATIONS_ERROR) && (be_list[0] == NULL)))
- {
- send_ldap_result(pb, err_code, NULL, errorbuf, 0, NULL);
- rc = -1;
- goto free_and_return;
- }
- if (be_list[0] != NULL)
- {
- index = 0;
- if (pr_be) { /* PAGED RESULT: be is found from the previous paging. */
- /* move the index in the be_list which matches pr_be */
- while (be_list[index] && be_list[index+1] && pr_be != be_list[index])
- index++;
+ if (be_name == NULL) {
+ /* no specific backend was requested, use the mapping tree
+ */
+ err_code = slapi_mapping_tree_select_all(pb, be_list, referral_list, errorbuf);
+ if (((err_code != LDAP_SUCCESS) && (err_code != LDAP_OPERATIONS_ERROR) && (err_code != LDAP_REFERRAL))
+ || ((err_code == LDAP_OPERATIONS_ERROR) && (be_list[0] == NULL))) {
+ send_ldap_result(pb, err_code, NULL, errorbuf, 0, NULL);
+ rc = -1;
+ goto free_and_return;
+ }
+ if (be_list[0] != NULL) {
+ index = 0;
+ while (be_list[index] && be_list[index+1]) {
+ index++;
+ }
+ be = be_list[index];
} else {
- while (be_list[index] && be_list[index+1])
- index++;
+ be = NULL;
}
- /* "be" is either pr_be or the last backend */
- be = be_list[index];
- }
- else
- be = pr_be?pr_be:NULL;
- }
- else
- {
+ } else {
/* specific backend be_name was requested, use slapi_be_select_by_instance_name
*/
- if (pr_be) {
- be_single = be = pr_be;
- } else {
- be_single = be = slapi_be_select_by_instance_name(be_name);
- }
+ be_single = be = slapi_be_select_by_instance_name(be_name);
if (be_single) {
- slapi_be_Rlock(be_single);
+ slapi_be_Rlock(be_single);
}
be_list[0] = NULL;
referral_list[0] = NULL;
@@ -521,6 +506,7 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
if ( slapi_control_present (ctrlp, LDAP_CONTROL_PAGEDRESULTS,
&ctl_value, &iscritical) )
{
+ /* be is set only when this request is new. otherwise, prev be is honored. */
rc = pagedresults_parse_control_value(pb, ctl_value, &pagesize, &pr_idx, be);
/* Let's set pr_idx even if it fails; in case, pr_idx == -1. */
slapi_pblock_set(pb, SLAPI_PAGED_RESULTS_INDEX, &pr_idx);
@@ -529,13 +515,24 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
unsigned int opnote = SLAPI_OP_NOTE_SIMPLEPAGED;
op_set_pagedresults(operation);
pr_be = pagedresults_get_current_be(pb->pb_conn, pr_idx);
- pr_search_result = pagedresults_get_search_result(pb->pb_conn,
- operation,
- pr_idx);
- estimate =
- pagedresults_get_search_result_set_size_estimate(pb->pb_conn,
- operation,
- pr_idx);
+ if (be_name) {
+ if (pr_be != be_single) {
+ slapi_be_Unlock(be_single);
+ be_single = be = pr_be;
+ slapi_be_Rlock(be_single);
+ }
+ } else if (be_list[0]) {
+ if (pr_be) { /* PAGED RESULT: be is found from the previous paging. */
+ /* move the index in the be_list which matches pr_be */
+ index = 0;
+ while (be_list[index] && be_list[index+1] && pr_be != be_list[index]) {
+ index++;
+ }
+ be = be_list[index];
+ }
+ }
+ pr_search_result = pagedresults_get_search_result(pb->pb_conn, operation, pr_idx);
+ estimate = pagedresults_get_search_result_set_size_estimate(pb->pb_conn, operation, pr_idx);
if (pagedresults_get_unindexed(pb->pb_conn, operation, pr_idx)) {
opnote |= SLAPI_OP_NOTE_UNINDEXED;
}
@@ -680,7 +677,7 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
* change ONE-LEVEL searches to BASE
*/
- /* that's mean we only support one suffix per backend */
+ /* that means we only support one suffix per backend */
be_suffix = slapi_be_getsuffix(be, 0);
if (be_list[0] == NULL)
@@ -704,9 +701,7 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
* In async paged result case, the search result might be released
* by other theads. We need to double check it in the locked region.
*/
- pr_search_result = pagedresults_get_search_result(pb->pb_conn,
- operation,
- pr_idx);
+ pr_search_result = pagedresults_get_search_result(pb->pb_conn, operation, pr_idx);
if (pr_search_result) {
slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET, pr_search_result );
rc = send_results_ext (pb, 1, &pnentries, pagesize, &pr_stat);
--
1.9.3