浏览代码

Ticket #48250 - Slapd crashes reported from latest build

Bug Description: There was a conflict between an import task and
deleting the instance.  While the import task was still running,
the backend instance was removed, which should have been rejected.

Fix Description: Backend tasks keeps instance refcnt positive and
disable the backend in the mapping tree.  This patch adds the
check for the mapping tree in the backend deletion callback.  If
the instance refcnt is positive or the mapping tree is disabled,
the deletion is backed off.

For the backend deletion, the referral info is not needed.  To
reduce unnecessary allocation and free, adding the code which
checks if the given referral variable is NULL or not to mtn_get_be.
If it is NULL, no allocation for the referral entry occurs.

https://fedorahosted.org/389/ticket/48250

Reviewed by [email protected] (Thank you, Rich!!)
Noriko Hosoi 10 年之前
父节点
当前提交
01fea1f89a
共有 2 个文件被更改,包括 39 次插入24 次删除
  1. 8 3
      ldap/servers/slapd/back-ldbm/ldbm_index_config.c
  2. 31 21
      ldap/servers/slapd/mapping_tree.c

+ 8 - 3
ldap/servers/slapd/back-ldbm/ldbm_index_config.c

@@ -128,7 +128,7 @@ ldbm_instance_index_config_add_callback(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_
 
 
 /*
 /*
  * Config DSE callback for index deletes.
  * Config DSE callback for index deletes.
- */	
+ */
 int 
 int 
 ldbm_instance_index_config_delete_callback(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, int *returncode, char *returntext, void *arg) 
 ldbm_instance_index_config_delete_callback(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, int *returncode, char *returntext, void *arg) 
 { 
 { 
@@ -138,15 +138,19 @@ ldbm_instance_index_config_delete_callback(Slapi_PBlock *pb, Slapi_Entry* e, Sla
   const struct berval *attrValue;
   const struct berval *attrValue;
   int rc = SLAPI_DSE_CALLBACK_OK;
   int rc = SLAPI_DSE_CALLBACK_OK;
   struct attrinfo *ainfo = NULL;
   struct attrinfo *ainfo = NULL;
+  Slapi_Backend *be = NULL;
   
   
   returntext[0] = '\0';
   returntext[0] = '\0';
   *returncode = LDAP_SUCCESS;
   *returncode = LDAP_SUCCESS;
 
 
-  if (slapi_counter_get_value(inst->inst_ref_count) > 0) {
+  if ((slapi_counter_get_value(inst->inst_ref_count) > 0) ||
+      /* check if the backend is ON or not. 
+       * If offline or being deleted, non SUCCESS is returned. */
+      (slapi_mapping_tree_select(pb, &be, NULL, returntext) != LDAP_SUCCESS)) {
     *returncode = LDAP_UNAVAILABLE;
     *returncode = LDAP_UNAVAILABLE;
     rc = SLAPI_DSE_CALLBACK_ERROR;
     rc = SLAPI_DSE_CALLBACK_ERROR;
+    goto bail;
   }
   }
-
   *returncode = LDAP_SUCCESS;
   *returncode = LDAP_SUCCESS;
   
   
   slapi_entry_attr_find(e, "cn", &attr);
   slapi_entry_attr_find(e, "cn", &attr);
@@ -165,6 +169,7 @@ ldbm_instance_index_config_delete_callback(Slapi_PBlock *pb, Slapi_Entry* e, Sla
       rc = SLAPI_DSE_CALLBACK_ERROR;
       rc = SLAPI_DSE_CALLBACK_ERROR;
     }
     }
   }
   }
+bail:
   return rc;
   return rc;
 }
 }
 
 

+ 31 - 21
ldap/servers/slapd/mapping_tree.c

@@ -2171,7 +2171,9 @@ int slapi_mapping_tree_select(Slapi_PBlock *pb, Slapi_Backend **be, Slapi_Entry
     } 
     } 
 
 
     be[0] = NULL;
     be[0] = NULL;
-    referral[0] = NULL;
+    if (referral) {
+        referral[0] = NULL;
+    }
 
 
     mtn_lock();
     mtn_lock();
 
 
@@ -2658,7 +2660,9 @@ static int mtn_get_be(mapping_tree_node *target_node, Slapi_PBlock *pb,
          ((SLAPI_OPERATION_SEARCH == op_type)||(SLAPI_OPERATION_BIND == op_type) || 
          ((SLAPI_OPERATION_SEARCH == op_type)||(SLAPI_OPERATION_BIND == op_type) || 
          (SLAPI_OPERATION_UNBIND == op_type) || (SLAPI_OPERATION_COMPARE == op_type))) ||
          (SLAPI_OPERATION_UNBIND == op_type) || (SLAPI_OPERATION_COMPARE == op_type))) ||
         override_referral) {
         override_referral) {
-        *referral = NULL;
+        if (referral) {
+            *referral = NULL;
+        }
         if ((target_node == mapping_tree_root) ){
         if ((target_node == mapping_tree_root) ){
             /* If we got here, then we couldn't find a matching node 
             /* If we got here, then we couldn't find a matching node 
              * for the target. We'll use the default backend.  Once
              * for the target. We'll use the default backend.  Once
@@ -2679,22 +2683,25 @@ static int mtn_get_be(mapping_tree_node *target_node, Slapi_PBlock *pb,
                     /* there is only one backend no choice possible */
                     /* there is only one backend no choice possible */
                     *index = 0;
                     *index = 0;
                 } else {
                 } else {
-                    *index = mtn_get_be_distributed(pb, target_node,
-                         target_sdn, &flag_stop);
-			if (*index == SLAPI_BE_NO_BACKEND) 
-				result = LDAP_UNWILLING_TO_PERFORM;
-            	}
-           }
-	   if (*index == SLAPI_BE_REMOTE_BACKEND) {
-           	*be = NULL;
-               	*referral = (target_node->mtn_referral_entry ?
-                       		slapi_entry_dup(target_node->mtn_referral_entry) :
-                       		NULL);
+                    *index = mtn_get_be_distributed(pb, target_node, target_sdn, &flag_stop);
+                    if (*index == SLAPI_BE_NO_BACKEND) {
+                        result = LDAP_UNWILLING_TO_PERFORM;
+                    }
+                }
+            }
+            if (*index == SLAPI_BE_REMOTE_BACKEND) {
+                *be = NULL;
+                if (referral) {
+                    *referral = (target_node->mtn_referral_entry ?
+                                slapi_entry_dup(target_node->mtn_referral_entry) : NULL);
+                }
                 (*index)++;
                 (*index)++;
             }else if ((*index == SLAPI_BE_NO_BACKEND) || (*index >= target_node->mtn_be_count)) {
             }else if ((*index == SLAPI_BE_NO_BACKEND) || (*index >= target_node->mtn_be_count)) {
-        	/* we have already returned all backends -> return NULL */
+                /* we have already returned all backends -> return NULL */
                 *be = NULL;
                 *be = NULL;
-                *referral = NULL;
+                if (referral) {
+                    *referral = NULL;
+                }
             } else {
             } else {
                 /* return next backend, increment index */
                 /* return next backend, increment index */
                 *be = target_node->mtn_be[*index];
                 *be = target_node->mtn_be[*index];
@@ -2749,7 +2756,9 @@ static int mtn_get_be(mapping_tree_node *target_node, Slapi_PBlock *pb,
              * send back NULL to jump to next node 
              * send back NULL to jump to next node 
              */
              */
             *be = NULL;
             *be = NULL;
-            *referral = NULL;
+            if (referral) {
+                *referral = NULL;
+            }
             result = LDAP_SUCCESS;
             result = LDAP_SUCCESS;
         } else {
         } else {
             /* first time we hit this referral -> return it
             /* first time we hit this referral -> return it
@@ -2758,11 +2767,12 @@ static int mtn_get_be(mapping_tree_node *target_node, Slapi_PBlock *pb,
              * returned this referral
              * returned this referral
              */
              */
             *be = NULL;
             *be = NULL;
-            *referral = (target_node->mtn_referral_entry ?
-                         slapi_entry_dup(target_node->mtn_referral_entry) :
-                         NULL);
+            if (referral) {
+                *referral = (target_node->mtn_referral_entry ?
+                             slapi_entry_dup(target_node->mtn_referral_entry) : NULL);
+            }
             (*index)++;
             (*index)++;
-            if (NULL == *referral) {
+            if (NULL == target_node->mtn_referral_entry) {
                 if (errorbuf) {
                 if (errorbuf) {
                     PR_snprintf(errorbuf, BUFSIZ,
                     PR_snprintf(errorbuf, BUFSIZ,
                     "Mapping tree node for %s is set to return a referral,"
                     "Mapping tree node for %s is set to return a referral,"
@@ -2782,7 +2792,7 @@ static int mtn_get_be(mapping_tree_node *target_node, Slapi_PBlock *pb,
                 "mapping tree selected backend : %s\n",
                 "mapping tree selected backend : %s\n",
                 slapi_be_get_name(*be));
                 slapi_be_get_name(*be));
             slapi_be_Rlock(*be);
             slapi_be_Rlock(*be);
-        } else if (*referral) {
+        } else if (referral && *referral) {
             slapi_log_error(SLAPI_LOG_ARGS, NULL,
             slapi_log_error(SLAPI_LOG_ARGS, NULL,
                 "mapping tree selected referral at node : %s\n",
                 "mapping tree selected referral at node : %s\n",
                 slapi_sdn_get_dn(target_node->mtn_subtree));
                 slapi_sdn_get_dn(target_node->mtn_subtree));