andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 6 months ago
Clone

Blame SOURCES/0045-Ticket-48250-Slapd-crashes-reported-from-latest-buil.patch

a2f18f
From 0cf9e38234476a0f3680ea388351f9bf90735818 Mon Sep 17 00:00:00 2001
a2f18f
From: Noriko Hosoi <nhosoi@redhat.com>
a2f18f
Date: Fri, 14 Aug 2015 11:19:24 -0700
a2f18f
Subject: [PATCH 45/45] Ticket #48250 - Slapd crashes reported from latest
a2f18f
 build
a2f18f
a2f18f
Bug Description: There was a conflict between an import task and
a2f18f
deleting the instance.  While the import task was still running,
a2f18f
the backend instance was removed, which should have been rejected.
a2f18f
a2f18f
Fix Description: Backend tasks keeps instance refcnt positive and
a2f18f
disable the backend in the mapping tree.  This patch adds the
a2f18f
check for the mapping tree in the backend deletion callback.  If
a2f18f
the instance refcnt is positive or the mapping tree is disabled,
a2f18f
the deletion is backed off.
a2f18f
a2f18f
For the backend deletion, the referral info is not needed.  To
a2f18f
reduce unnecessary allocation and free, adding the code which
a2f18f
checks if the given referral variable is NULL or not to mtn_get_be.
a2f18f
If it is NULL, no allocation for the referral entry occurs.
a2f18f
a2f18f
https://fedorahosted.org/389/ticket/48250
a2f18f
a2f18f
Reviewed by rmeggins@redhat.com (Thank you, Rich!!)
a2f18f
a2f18f
(cherry picked from commit 01fea1f89a680358245677f72a67e9ccf196f66d)
a2f18f
(cherry picked from commit 7a4b0a705ec7376e704f6ae591beabf6c8f890af)
a2f18f
---
a2f18f
 ldap/servers/slapd/back-ldbm/ldbm_index_config.c | 11 +++--
a2f18f
 ldap/servers/slapd/mapping_tree.c                | 52 ++++++++++++++----------
a2f18f
 2 files changed, 39 insertions(+), 24 deletions(-)
a2f18f
a2f18f
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
a2f18f
index 895d846..42c8ffe 100644
a2f18f
--- a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
a2f18f
+++ b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
a2f18f
@@ -128,7 +128,7 @@ ldbm_instance_index_config_add_callback(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_
a2f18f
 
a2f18f
 /*
a2f18f
  * Config DSE callback for index deletes.
a2f18f
- */	
a2f18f
+ */
a2f18f
 int 
a2f18f
 ldbm_instance_index_config_delete_callback(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, int *returncode, char *returntext, void *arg) 
a2f18f
 { 
a2f18f
@@ -138,15 +138,19 @@ ldbm_instance_index_config_delete_callback(Slapi_PBlock *pb, Slapi_Entry* e, Sla
a2f18f
   const struct berval *attrValue;
a2f18f
   int rc = SLAPI_DSE_CALLBACK_OK;
a2f18f
   struct attrinfo *ainfo = NULL;
a2f18f
+  Slapi_Backend *be = NULL;
a2f18f
   
a2f18f
   returntext[0] = '\0';
a2f18f
   *returncode = LDAP_SUCCESS;
a2f18f
 
a2f18f
-  if (slapi_counter_get_value(inst->inst_ref_count) > 0) {
a2f18f
+  if ((slapi_counter_get_value(inst->inst_ref_count) > 0) ||
a2f18f
+      /* check if the backend is ON or not. 
a2f18f
+       * If offline or being deleted, non SUCCESS is returned. */
a2f18f
+      (slapi_mapping_tree_select(pb, &be, NULL, returntext) != LDAP_SUCCESS)) {
a2f18f
     *returncode = LDAP_UNAVAILABLE;
a2f18f
     rc = SLAPI_DSE_CALLBACK_ERROR;
a2f18f
+    goto bail;
a2f18f
   }
a2f18f
-
a2f18f
   *returncode = LDAP_SUCCESS;
a2f18f
   
a2f18f
   slapi_entry_attr_find(e, "cn", &attr);
a2f18f
@@ -165,6 +169,7 @@ ldbm_instance_index_config_delete_callback(Slapi_PBlock *pb, Slapi_Entry* e, Sla
a2f18f
       rc = SLAPI_DSE_CALLBACK_ERROR;
a2f18f
     }
a2f18f
   }
a2f18f
+bail:
a2f18f
   return rc;
a2f18f
 }
a2f18f
 
a2f18f
diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c
a2f18f
index ca8d6af..165eba1 100644
a2f18f
--- a/ldap/servers/slapd/mapping_tree.c
a2f18f
+++ b/ldap/servers/slapd/mapping_tree.c
a2f18f
@@ -2171,7 +2171,9 @@ int slapi_mapping_tree_select(Slapi_PBlock *pb, Slapi_Backend **be, Slapi_Entry
a2f18f
     } 
a2f18f
 
a2f18f
     be[0] = NULL;
a2f18f
-    referral[0] = NULL;
a2f18f
+    if (referral) {
a2f18f
+        referral[0] = NULL;
a2f18f
+    }
a2f18f
 
a2f18f
     mtn_lock();
a2f18f
 
a2f18f
@@ -2658,7 +2660,9 @@ static int mtn_get_be(mapping_tree_node *target_node, Slapi_PBlock *pb,
a2f18f
          ((SLAPI_OPERATION_SEARCH == op_type)||(SLAPI_OPERATION_BIND == op_type) || 
a2f18f
          (SLAPI_OPERATION_UNBIND == op_type) || (SLAPI_OPERATION_COMPARE == op_type))) ||
a2f18f
         override_referral) {
a2f18f
-        *referral = NULL;
a2f18f
+        if (referral) {
a2f18f
+            *referral = NULL;
a2f18f
+        }
a2f18f
         if ((target_node == mapping_tree_root) ){
a2f18f
             /* If we got here, then we couldn't find a matching node 
a2f18f
              * for the target. We'll use the default backend.  Once
a2f18f
@@ -2679,22 +2683,25 @@ static int mtn_get_be(mapping_tree_node *target_node, Slapi_PBlock *pb,
a2f18f
                     /* there is only one backend no choice possible */
a2f18f
                     *index = 0;
a2f18f
                 } else {
a2f18f
-                    *index = mtn_get_be_distributed(pb, target_node,
a2f18f
-                         target_sdn, &flag_stop);
a2f18f
-			if (*index == SLAPI_BE_NO_BACKEND) 
a2f18f
-				result = LDAP_UNWILLING_TO_PERFORM;
a2f18f
-            	}
a2f18f
-           }
a2f18f
-	   if (*index == SLAPI_BE_REMOTE_BACKEND) {
a2f18f
-           	*be = NULL;
a2f18f
-               	*referral = (target_node->mtn_referral_entry ?
a2f18f
-                       		slapi_entry_dup(target_node->mtn_referral_entry) :
a2f18f
-                       		NULL);
a2f18f
+                    *index = mtn_get_be_distributed(pb, target_node, target_sdn, &flag_stop);
a2f18f
+                    if (*index == SLAPI_BE_NO_BACKEND) {
a2f18f
+                        result = LDAP_UNWILLING_TO_PERFORM;
a2f18f
+                    }
a2f18f
+                }
a2f18f
+            }
a2f18f
+            if (*index == SLAPI_BE_REMOTE_BACKEND) {
a2f18f
+                *be = NULL;
a2f18f
+                if (referral) {
a2f18f
+                    *referral = (target_node->mtn_referral_entry ?
a2f18f
+                                slapi_entry_dup(target_node->mtn_referral_entry) : NULL);
a2f18f
+                }
a2f18f
                 (*index)++;
a2f18f
             }else if ((*index == SLAPI_BE_NO_BACKEND) || (*index >= target_node->mtn_be_count)) {
a2f18f
-        	/* we have already returned all backends -> return NULL */
a2f18f
+                /* we have already returned all backends -> return NULL */
a2f18f
                 *be = NULL;
a2f18f
-                *referral = NULL;
a2f18f
+                if (referral) {
a2f18f
+                    *referral = NULL;
a2f18f
+                }
a2f18f
             } else {
a2f18f
                 /* return next backend, increment index */
a2f18f
                 *be = target_node->mtn_be[*index];
a2f18f
@@ -2749,7 +2756,9 @@ static int mtn_get_be(mapping_tree_node *target_node, Slapi_PBlock *pb,
a2f18f
              * send back NULL to jump to next node 
a2f18f
              */
a2f18f
             *be = NULL;
a2f18f
-            *referral = NULL;
a2f18f
+            if (referral) {
a2f18f
+                *referral = NULL;
a2f18f
+            }
a2f18f
             result = LDAP_SUCCESS;
a2f18f
         } else {
a2f18f
             /* first time we hit this referral -> return it
a2f18f
@@ -2758,11 +2767,12 @@ static int mtn_get_be(mapping_tree_node *target_node, Slapi_PBlock *pb,
a2f18f
              * returned this referral
a2f18f
              */
a2f18f
             *be = NULL;
a2f18f
-            *referral = (target_node->mtn_referral_entry ?
a2f18f
-                         slapi_entry_dup(target_node->mtn_referral_entry) :
a2f18f
-                         NULL);
a2f18f
+            if (referral) {
a2f18f
+                *referral = (target_node->mtn_referral_entry ?
a2f18f
+                             slapi_entry_dup(target_node->mtn_referral_entry) : NULL);
a2f18f
+            }
a2f18f
             (*index)++;
a2f18f
-            if (NULL == *referral) {
a2f18f
+            if (NULL == target_node->mtn_referral_entry) {
a2f18f
                 if (errorbuf) {
a2f18f
                     PR_snprintf(errorbuf, BUFSIZ,
a2f18f
                     "Mapping tree node for %s is set to return a referral,"
a2f18f
@@ -2782,7 +2792,7 @@ static int mtn_get_be(mapping_tree_node *target_node, Slapi_PBlock *pb,
a2f18f
                 "mapping tree selected backend : %s\n",
a2f18f
                 slapi_be_get_name(*be));
a2f18f
             slapi_be_Rlock(*be);
a2f18f
-        } else if (*referral) {
a2f18f
+        } else if (referral && *referral) {
a2f18f
             slapi_log_error(SLAPI_LOG_ARGS, NULL,
a2f18f
                 "mapping tree selected referral at node : %s\n",
a2f18f
                 slapi_sdn_get_dn(target_node->mtn_subtree));
a2f18f
-- 
a2f18f
1.9.3
a2f18f