Blame SOURCES/0066-Ticket-48146-async-simple-paged-results-issue-need-t.patch

df9752
From 39e430f55e61605d27849c0f17e37e046cbbda72 Mon Sep 17 00:00:00 2001
df9752
From: Noriko Hosoi <nhosoi@redhat.com>
df9752
Date: Fri, 1 May 2015 12:01:13 -0700
df9752
Subject: [PATCH 66/72] Ticket #48146 - async simple paged results issue; need
df9752
 to close a small window for a pr index competed among multiple threads.
df9752
df9752
Description: If multiple async simple paged results requests come in via one
df9752
connection simultaneously, the same slot in the paged results array in the
df9752
connection could be shared.  If one of them has to do paging, the search
df9752
request object stashed in the paged result array slot could be freed by the
df9752
other request if it has the shorter life cycle.
df9752
df9752
These 3 reqs use the same paged results array slot.
df9752
req0: <--------------><----x
df9752
page1           page2
df9752
req1: <----->
df9752
req2:              <------->
df9752
frees search result object of req0
df9752
df9752
Reviewed by rmeggins@redhat.com (Thank you, Rich!!)
df9752
df9752
(cherry picked from commit 3cf85d1ad6cbc0feac5578dee5ce259c0f65055f)
df9752
---
df9752
 ldap/servers/slapd/opshared.c     | 93 +++++++++++++++++++--------------------
df9752
 ldap/servers/slapd/pagedresults.c |  3 +-
df9752
 ldap/servers/slapd/proto-slap.h   |  2 +-
df9752
 3 files changed, 49 insertions(+), 49 deletions(-)
df9752
df9752
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
df9752
index e7cee8a..430b0c6 100644
df9752
--- a/ldap/servers/slapd/opshared.c
df9752
+++ b/ldap/servers/slapd/opshared.c
df9752
@@ -408,6 +408,51 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
df9752
    */
df9752
   operation_set_target_spec (pb->pb_op, basesdn);
df9752
 
df9752
+  if (be_name == NULL)
df9752
+  {
df9752
+    /* no specific backend was requested, use the mapping tree
df9752
+     */
df9752
+    err_code = slapi_mapping_tree_select_all(pb, be_list, referral_list, errorbuf);
df9752
+    if (((err_code != LDAP_SUCCESS) && (err_code != LDAP_OPERATIONS_ERROR) && (err_code != LDAP_REFERRAL))
df9752
+      || ((err_code == LDAP_OPERATIONS_ERROR) && (be_list[0] == NULL)))
df9752
+    {
df9752
+      send_ldap_result(pb, err_code, NULL, errorbuf, 0, NULL);
df9752
+      rc = -1;
df9752
+      goto free_and_return;
df9752
+    }
df9752
+    if (be_list[0] != NULL)
df9752
+    {
df9752
+      index = 0;
df9752
+      if (pr_be) { /* PAGED RESULT: be is found from the previous paging. */
df9752
+        /* move the index in the be_list which matches pr_be */
df9752
+        while (be_list[index] && be_list[index+1] && pr_be != be_list[index])
df9752
+          index++;
df9752
+      } else {
df9752
+        while (be_list[index] && be_list[index+1])
df9752
+          index++;
df9752
+      }
df9752
+      /* "be" is either pr_be or the last backend */
df9752
+      be = be_list[index];
df9752
+    }
df9752
+    else
df9752
+      be = pr_be?pr_be:NULL;
df9752
+  }
df9752
+  else
df9752
+  {
df9752
+      /* specific backend be_name was requested, use slapi_be_select_by_instance_name
df9752
+       */
df9752
+      if (pr_be) {
df9752
+        be_single = be = pr_be;
df9752
+      } else {
df9752
+        be_single = be = slapi_be_select_by_instance_name(be_name);
df9752
+      }
df9752
+      if (be_single)
df9752
+        slapi_be_Rlock(be_single);
df9752
+      be_list[0] = NULL;
df9752
+      referral_list[0] = NULL;
df9752
+      referral = NULL;
df9752
+  }
df9752
+
df9752
   /* this is time to check if mapping tree specific control
df9752
    * was used to specify that we want to parse only 
df9752
    * one backend 
df9752
@@ -478,8 +523,7 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
df9752
       if ( slapi_control_present (ctrlp, LDAP_CONTROL_PAGEDRESULTS,
df9752
                                   &ctl_value, &iscritical) )
df9752
       {
df9752
-          rc = pagedresults_parse_control_value(pb, ctl_value,
df9752
-                                                &pagesize, &pr_idx);
df9752
+          rc = pagedresults_parse_control_value(pb, ctl_value, &pagesize, &pr_idx, be);
df9752
           /* Let's set pr_idx even if it fails; in case, pr_idx == -1. */
df9752
           slapi_pblock_set(pb, SLAPI_PAGED_RESULTS_INDEX, &pr_idx);
df9752
           if ((LDAP_SUCCESS == rc) ||
df9752
@@ -520,51 +564,6 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
df9752
       }
df9752
   }
df9752
 
df9752
-  if (be_name == NULL)
df9752
-  {
df9752
-    /* no specific backend was requested, use the mapping tree
df9752
-     */
df9752
-    err_code = slapi_mapping_tree_select_all(pb, be_list, referral_list, errorbuf);
df9752
-    if (((err_code != LDAP_SUCCESS) && (err_code != LDAP_OPERATIONS_ERROR) && (err_code != LDAP_REFERRAL))
df9752
-      || ((err_code == LDAP_OPERATIONS_ERROR) && (be_list[0] == NULL)))
df9752
-    {
df9752
-      send_ldap_result(pb, err_code, NULL, errorbuf, 0, NULL);
df9752
-      rc = -1;
df9752
-      goto free_and_return;
df9752
-    }
df9752
-    if (be_list[0] != NULL)
df9752
-    {
df9752
-      index = 0;
df9752
-      if (pr_be) { /* PAGED RESULT: be is found from the previous paging. */
df9752
-        /* move the index in the be_list which matches pr_be */
df9752
-        while (be_list[index] && be_list[index+1] && pr_be != be_list[index])
df9752
-          index++;
df9752
-      } else {
df9752
-        while (be_list[index] && be_list[index+1])
df9752
-          index++;
df9752
-      }
df9752
-      /* "be" is either pr_be or the last backend */
df9752
-      be = be_list[index];
df9752
-    }
df9752
-    else
df9752
-      be = pr_be?pr_be:NULL;
df9752
-  }
df9752
-  else
df9752
-  {
df9752
-      /* specific backend be_name was requested, use slapi_be_select_by_instance_name
df9752
-       */
df9752
-      if (pr_be) {
df9752
-        be_single = be = pr_be;
df9752
-      } else {
df9752
-        be_single = be = slapi_be_select_by_instance_name(be_name);
df9752
-      }
df9752
-      if (be_single)
df9752
-        slapi_be_Rlock(be_single);
df9752
-      be_list[0] = NULL;
df9752
-      referral_list[0] = NULL;
df9752
-      referral = NULL;
df9752
-  }
df9752
-
df9752
   slapi_pblock_set(pb, SLAPI_BACKEND_COUNT, &index);
df9752
 
df9752
   if (be)
df9752
diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c
df9752
index e61c000..a3a5fc4 100644
df9752
--- a/ldap/servers/slapd/pagedresults.c
df9752
+++ b/ldap/servers/slapd/pagedresults.c
df9752
@@ -58,7 +58,7 @@
df9752
 int
df9752
 pagedresults_parse_control_value( Slapi_PBlock *pb,
df9752
                                   struct berval *psbvp, ber_int_t *pagesize,
df9752
-                                  int *index )
df9752
+                                  int *index, Slapi_Backend *be )
df9752
 {
df9752
     int rc = LDAP_SUCCESS;
df9752
     struct berval cookie = {0};
df9752
@@ -119,6 +119,7 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
df9752
         } else {
df9752
             for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++) {
df9752
                 if (!conn->c_pagedresults.prl_list[i].pr_current_be) {
df9752
+                    conn->c_pagedresults.prl_list[i].pr_current_be = be;
df9752
                     *index = i;
df9752
                     break;
df9752
                 }
df9752
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
df9752
index c987b4a..80504b2 100644
df9752
--- a/ldap/servers/slapd/proto-slap.h
df9752
+++ b/ldap/servers/slapd/proto-slap.h
df9752
@@ -1467,7 +1467,7 @@ int slapd_do_all_nss_ssl_init(int slapd_exemode, int importexport_encrypt,
df9752
  * pagedresults.c
df9752
  */
df9752
 int pagedresults_parse_control_value(Slapi_PBlock *pb, struct berval *psbvp,
df9752
-                                     ber_int_t *pagesize, int *index);
df9752
+                                     ber_int_t *pagesize, int *index, Slapi_Backend *be);
df9752
 void pagedresults_set_response_control(Slapi_PBlock *pb, int iscritical, 
df9752
                                        ber_int_t estimate,
df9752
                                        int curr_search_count, int index);
df9752
-- 
df9752
1.9.3
df9752