andykimpe / rpms / 389-ds-base

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