ldap/servers/slapd/back-ldbm/back-ldbm.h | 4 -- ldap/servers/slapd/back-ldbm/dblayer.c | 22 +++++++---- ldap/servers/slapd/back-ldbm/id2entry.c | 6 +++ ldap/servers/slapd/back-ldbm/import-merge.c | 4 +- ldap/servers/slapd/back-ldbm/instance.c | 4 ++ ldap/servers/slapd/back-ldbm/ldbm_add.c | 18 +++++++-- ldap/servers/slapd/back-ldbm/ldbm_bind.c | 33 ++++++++++++---- ldap/servers/slapd/back-ldbm/ldbm_compare.c | 18 +++++++-- ldap/servers/slapd/back-ldbm/ldbm_delete.c | 13 ++++++ ldap/servers/slapd/back-ldbm/ldbm_index_config.c | 8 +++- ldap/servers/slapd/back-ldbm/ldbm_instance_config.c | 3 + ldap/servers/slapd/back-ldbm/ldbm_modify.c | 11 +++++ ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 12 ++++++ ldap/servers/slapd/back-ldbm/ldbm_search.c | 39 +++++++++++--------- ldap/servers/slapd/back-ldbm/ldif2ldbm.c | 3 + ldap/servers/slapd/back-ldbm/misc.c | 10 ++++- ldap/servers/slapd/back-ldbm/proto-back-ldbm.h | 3 + ldap/servers/slapd/back-ldbm/vlv.c | 2 - 18 files changed, 163 insertions(+), 50 deletions(-)
New commits: commit 7f81635990fa340e2db5c1b14a8d1ba10fa53887 Author: Noriko Hosoi nhosoi@totoro.usersys.redhat.com Date: Fri Oct 26 12:09:18 2012 -0700
Trac Ticket #391 - Slapd crashes when deleting backends while operations are still in progress
https://fedorahosted.org/389/ticket/391
Bug Description: Deleting backend code ldbm_instance_delete_instance_ entry_callback had no checking for the ordinary operations accessing the backend instance. Even if some operations are still in progress, the backend instance could be deleted and it crashes the server.
Fix Description: Backend struct ldbm_instance had a member inst_ref_ count, which was not used. This patch converts the type PRInt32 to Slapi_Counter and increments it when the backend instance is in use. The delete code checks the counter and if it is greater than 0, it returns SLAPI_DSE_CALLBACK_ERROR.
diff --git a/ldap/servers/slapd/back-ldbm/back-ldbm.h b/ldap/servers/slapd/back-ldbm/back-ldbm.h index fb45a9f..39fd950 100644 --- a/ldap/servers/slapd/back-ldbm/back-ldbm.h +++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h @@ -735,10 +735,8 @@ typedef struct ldbm_instance { int inst_flags; /* see above */
PRLock *inst_config_mutex; - - PRInt32 *inst_ref_count; /* Keeps track of how many operations + Slapi_Counter *inst_ref_count; /* Keeps track of how many operations * are currently using this instance */ - char *inst_dir_name; /* The name of the directory in the db * directory that holds the index files * for this instance. Relative to the diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c index ed7d770..26007f4 100644 --- a/ldap/servers/slapd/back-ldbm/dblayer.c +++ b/ldap/servers/slapd/back-ldbm/dblayer.c @@ -3103,14 +3103,20 @@ out: slapi_ch_free((void**)&rel_path); /* close the database handle to avoid handle leak */ if (dbp && (return_value != 0)) { - dblayer_close_file(dbp); + dblayer_close_file(&dbp); } return return_value; }
-int dblayer_close_file(DB *db) +int +dblayer_close_file(DB **db) { - return db->close(db,0); + if (db) { + DB *dbp = *db; + *db = NULL; /* To avoid to leave stale DB, set NULL before closing. */ + return dbp->close(dbp, 0); + } + return 1; }
/* @@ -3163,7 +3169,7 @@ int dblayer_get_index_file(backend *be, struct attrinfo *a, DB** ppDB, int open_ */ PR_AtomicIncrement(&a->ai_dblayer_count);
- if (NULL != a->ai_dblayer) { + if (a->ai_dblayer && ((dblayer_handle*)(a->ai_dblayer))->dblayer_dbp) { /* This means that the pointer is valid, so we should return it. */ *ppDB = ((dblayer_handle*)(a->ai_dblayer))->dblayer_dbp; return 0; @@ -3173,7 +3179,7 @@ int dblayer_get_index_file(backend *be, struct attrinfo *a, DB** ppDB, int open_ * again. */ PR_Lock(inst->inst_handle_list_mutex); - if (NULL != a->ai_dblayer) { + if (a->ai_dblayer && ((dblayer_handle*)(a->ai_dblayer))->dblayer_dbp) { /* another thread set the handle while we were waiting on the lock */ *ppDB = ((dblayer_handle*)(a->ai_dblayer))->dblayer_dbp; PR_Unlock(inst->inst_handle_list_mutex); @@ -3316,6 +3322,7 @@ int dblayer_erase_index_file_ex(backend *be, struct attrinfo *a,
if (0 == dblayer_get_index_file(be, a, &db, 0 /* Don't create an index file if it does not exist. */)) { + if(use_lock) slapi_rwlock_wrlock(pEnv->dblayer_env_lock); /* We will be causing logging activity */ /* first, remove the file handle for this index, if we have it open */ PR_Lock(inst->inst_handle_list_mutex); if (a->ai_dblayer) { @@ -3340,7 +3347,7 @@ int dblayer_erase_index_file_ex(backend *be, struct attrinfo *a, DS_Sleep(DBLAYER_CACHE_DELAY); PR_Lock(inst->inst_handle_list_mutex); } - dblayer_close_file(handle->dblayer_dbp); + dblayer_close_file(&(handle->dblayer_dbp));
/* remove handle from handle-list */ if (inst->inst_handle_head == handle) { @@ -3372,7 +3379,7 @@ int dblayer_erase_index_file_ex(backend *be, struct attrinfo *a, p = dbNamep + dbbasenamelen; sprintf(p, "%c%s%s", get_sep(dbNamep), a->ai_type, LDBM_FILENAME_SUFFIX); - rc = dblayer_db_remove_ex(pEnv, dbNamep, 0, use_lock); + rc = dblayer_db_remove_ex(pEnv, dbNamep, 0, 0); a->ai_dblayer = NULL; if (dbNamep != dbName) slapi_ch_free_string(&dbNamep); @@ -3386,6 +3393,7 @@ int dblayer_erase_index_file_ex(backend *be, struct attrinfo *a, /* no handle to close */ } PR_Unlock(inst->inst_handle_list_mutex); + if(use_lock) slapi_rwlock_unlock(pEnv->dblayer_env_lock);
}
diff --git a/ldap/servers/slapd/back-ldbm/id2entry.c b/ldap/servers/slapd/back-ldbm/id2entry.c index e278a2a..4d9c111 100644 --- a/ldap/servers/slapd/back-ldbm/id2entry.c +++ b/ldap/servers/slapd/back-ldbm/id2entry.c @@ -382,6 +382,12 @@ id2entry( backend *be, ID id, back_txn *txn, int *err ) "(rdn=%s, ID=%d)\n", rdn, id); /* Try rdn as dn. Could be RUV. */ normdn = slapi_ch_strdup(rdn); + } else if (NULL == normdn) { + slapi_log_error(SLAPI_LOG_FATAL, ID2ENTRY, + "<= id2entry( %lu ) entryrdn_lookup_dn returned NULL. " + "Index file may be deleted or corrupted.\n", + (u_long)id); + goto bail; } sdn = slapi_sdn_new_normdn_byval((const char *)normdn); bdn = backdn_init(sdn, id, 0); diff --git a/ldap/servers/slapd/back-ldbm/import-merge.c b/ldap/servers/slapd/back-ldbm/import-merge.c index 9d7af3e..d5be665 100644 --- a/ldap/servers/slapd/back-ldbm/import-merge.c +++ b/ldap/servers/slapd/back-ldbm/import-merge.c @@ -593,7 +593,7 @@ static int import_merge_one_file(ImportWorkerInfo *worker, int passes, } preclose_ret = ret; /* Now close the files */ - dblayer_close_file(output_file); + dblayer_close_file(&output_file); /* Close the cursors */ /* Close and delete the files */ for (i = 0; i < passes; i++) { @@ -605,7 +605,7 @@ static int import_merge_one_file(ImportWorkerInfo *worker, int passes, if (0 != ret) { import_log_notice(worker->job, "MERGE FAIL 4"); } - ret = dblayer_close_file(db); + ret = dblayer_close_file(&db); if (0 != ret) { import_log_notice(worker->job, "MERGE FAIL 5"); } diff --git a/ldap/servers/slapd/back-ldbm/instance.c b/ldap/servers/slapd/back-ldbm/instance.c index 6aa8212..e172279 100644 --- a/ldap/servers/slapd/back-ldbm/instance.c +++ b/ldap/servers/slapd/back-ldbm/instance.c @@ -123,6 +123,9 @@ int ldbm_instance_create(backend *be, char *name) goto error; }
+ /* Keeps track of how many operations are currently using this instance */ + inst->inst_ref_count = slapi_counter_new(); + inst->inst_be = be; inst->inst_li = li; be->be_instance_info = inst; @@ -411,6 +414,7 @@ ldbm_instance_destructor(void **arg) LDAPDebug(LDAP_DEBUG_ANY, "Destructor for instance %s called\n", inst->inst_name, 0, 0);
+ slapi_counter_destroy(&(inst->inst_ref_count)); slapi_ch_free_string(&inst->inst_name); PR_DestroyLock(inst->inst_config_mutex); slapi_ch_free_string(&inst->inst_dir_name); diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c index b8989fc..cf2676e 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_add.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c @@ -132,7 +132,15 @@ ldbm_back_add( Slapi_PBlock *pb ) is_ruv = operation_is_flag_set(operation, OP_FLAG_REPL_RUV);
inst = (ldbm_instance *) be->be_instance_info; - + if (inst->inst_ref_count) { + slapi_counter_increment(inst->inst_ref_count); + } else { + LDAPDebug1Arg(LDAP_DEBUG_ANY, + "ldbm_add: instance %s does not exist.\n", + inst->inst_name); + goto error_return; + } + /* sdn & parentsdn need to be initialized before "goto *_return" */ slapi_sdn_init(&parentsdn); @@ -878,8 +886,9 @@ ldbm_back_add( Slapi_PBlock *pb ) continue; } if (retval != 0) { - LDAPDebug( LDAP_DEBUG_ANY, "add: attempt to index %lu failed\n", - (u_long)addingentry->ep_id, 0, 0 ); + LDAPDebug2Args(LDAP_DEBUG_ANY, + "add: attempt to index %lu failed (rc=%d)\n", + (u_long)addingentry->ep_id, retval); ADD_SET_ERROR(ldap_result_code, LDAP_OPERATIONS_ERROR, retry_count); if (LDBM_OS_ERR_IS_DISKFULL(retval)) { disk_full = 1; @@ -1137,6 +1146,9 @@ common_return: } CACHE_RETURN( &inst->inst_cache, &addingentry ); } + if (inst->inst_ref_count) { + slapi_counter_decrement(inst->inst_ref_count); + } /* bepost op needs to know this result */ slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ldap_result_code); /* JCMREPL - The bepostop is called even if the operation fails. */ diff --git a/ldap/servers/slapd/back-ldbm/ldbm_bind.c b/ldap/servers/slapd/back-ldbm/ldbm_bind.c index 24c0b4f..f1dad38 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_bind.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_bind.c @@ -50,7 +50,7 @@ typedef enum LDAPWAEnum { LDAPWA_NoDomainAttr = -3, LDAPWA_InvalidCredentials = -2, LDAPWA_Failure = -1, - LDAPWA_Success= 0 + LDAPWA_Success= 0 } LDAPWAStatus;
int @@ -211,6 +211,7 @@ ldbm_back_bind( Slapi_PBlock *pb ) Slapi_Value **bvals; entry_address *addr; back_txn txn = {NULL}; + int rc = SLAPI_BIND_SUCCESS;
/* get parameters */ slapi_pblock_get( pb, SLAPI_BACKEND, &be ); @@ -226,10 +227,19 @@ ldbm_back_bind( Slapi_PBlock *pb ) } inst = (ldbm_instance *) be->be_instance_info; + if (inst->inst_ref_count) { + slapi_counter_increment(inst->inst_ref_count); + } else { + LDAPDebug1Arg(LDAP_DEBUG_ANY, + "ldbm_bind: instance %s does not exist.\n", + inst->inst_name); + return( SLAPI_BIND_FAIL ); + }
/* always allow noauth simple binds (front end will send the result) */ if ( method == LDAP_AUTH_SIMPLE && cred->bv_len == 0 ) { - return( SLAPI_BIND_ANONYMOUS ); + rc = SLAPI_BIND_ANONYMOUS; + goto bail; }
/* @@ -237,7 +247,8 @@ ldbm_back_bind( Slapi_PBlock *pb ) * and sending errors if the entry does not exist. */ if (( e = find_entry( pb, be, addr, &txn )) == NULL ) { - return( SLAPI_BIND_FAIL ); + rc = SLAPI_BIND_FAIL; + goto bail; }
switch ( method ) { @@ -253,7 +264,8 @@ ldbm_back_bind( Slapi_PBlock *pb ) slapi_send_ldap_result( pb, LDAP_INAPPROPRIATE_AUTH, NULL, NULL, 0, NULL ); CACHE_RETURN( &inst->inst_cache, &e ); - return( SLAPI_BIND_FAIL ); + rc = SLAPI_BIND_FAIL; + goto bail; } bvals= attr_get_present_values(attr); slapi_value_init_berval(&cv,cred); @@ -269,7 +281,8 @@ ldbm_back_bind( Slapi_PBlock *pb ) NULL, 0, NULL ); CACHE_RETURN( &inst->inst_cache, &e ); value_done(&cv); - return( SLAPI_BIND_FAIL ); + rc = SLAPI_BIND_FAIL; + goto bail; } value_done(&cv); } @@ -279,11 +292,15 @@ ldbm_back_bind( Slapi_PBlock *pb ) slapi_send_ldap_result( pb, LDAP_STRONG_AUTH_NOT_SUPPORTED, NULL, "auth method not supported", 0, NULL ); CACHE_RETURN( &inst->inst_cache, &e ); - return( SLAPI_BIND_FAIL ); + rc = SLAPI_BIND_FAIL; + goto bail; }
CACHE_RETURN( &inst->inst_cache, &e ); - +bail: + if (inst->inst_ref_count) { + slapi_counter_decrement(inst->inst_ref_count); + } /* success: front end will send result */ - return( SLAPI_BIND_SUCCESS ); + return rc; } diff --git a/ldap/servers/slapd/back-ldbm/ldbm_compare.c b/ldap/servers/slapd/back-ldbm/ldbm_compare.c index e9761ec..e201ca6 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_compare.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_compare.c @@ -61,7 +61,6 @@ ldbm_back_compare( Slapi_PBlock *pb ) Slapi_DN *namespace_dn; back_txn txn = {NULL};
- slapi_pblock_get( pb, SLAPI_BACKEND, &be ); slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li ); slapi_pblock_get( pb, SLAPI_TARGET_ADDRESS, &addr); @@ -75,16 +74,25 @@ ldbm_back_compare( Slapi_PBlock *pb ) }
inst = (ldbm_instance *) be->be_instance_info; + if (inst->inst_ref_count) { + slapi_counter_increment(inst->inst_ref_count); + } else { + LDAPDebug1Arg(LDAP_DEBUG_ANY, + "ldbm_compare: instance %s does not exist.\n", + inst->inst_name); + return -1; + } /* get the namespace dn */ namespace_dn = (Slapi_DN*)slapi_be_getsuffix(be, 0);
if ( (e = find_entry( pb, be, addr, &txn )) == NULL ) { - return( -1 ); /* error result sent by find_entry() */ + ret = -1; /* error result sent by find_entry() */ + goto bail; }
err = slapi_access_allowed (pb, e->ep_entry, type, bval, SLAPI_ACL_COMPARE); if ( err != LDAP_SUCCESS ) { - slapi_send_ldap_result( pb, err, NULL, NULL, 0, NULL ); + slapi_send_ldap_result( pb, err, NULL, NULL, 0, NULL ); ret = 1; } else {
@@ -117,5 +125,9 @@ ldbm_back_compare( Slapi_PBlock *pb ) }
CACHE_RETURN( &inst->inst_cache, &e ); +bail: + if (inst->inst_ref_count) { + slapi_counter_decrement(inst->inst_ref_count); + } return( ret ); } diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c index 57cc3b7..5661bfa 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c @@ -146,6 +146,14 @@ ldbm_back_delete( Slapi_PBlock *pb ) delete_tombstone_entry = operation_is_flag_set(operation, OP_FLAG_TOMBSTONE_ENTRY); inst = (ldbm_instance *) be->be_instance_info; + if (inst->inst_ref_count) { + slapi_counter_increment(inst->inst_ref_count); + } else { + LDAPDebug1Arg(LDAP_DEBUG_ANY, + "ldbm_delete: instance %s does not exist.\n", + inst->inst_name); + goto error_return; + }
/* The dblock serializes writes to the database, * which reduces deadlocking in the db code, @@ -1206,6 +1214,9 @@ common_return: CACHE_RETURN( &inst->inst_cache, &e ); } } + if (inst->inst_ref_count) { + slapi_counter_decrement(inst->inst_ref_count); + } if (ruv_c_init) { modify_term(&ruv_c, be); @@ -1214,7 +1225,7 @@ common_return: diskfull_return: if(ldap_result_code!=-1) { - slapi_send_ldap_result( pb, ldap_result_code, NULL, ldap_result_message, 0, NULL ); + slapi_send_ldap_result( pb, ldap_result_code, NULL, ldap_result_message, 0, NULL ); } modify_term(&parent_modify_c,be); if (rc == 0 && opcsn && !is_fixup_operation && !delete_tombstone_entry) diff --git a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c index 2775785..e2bec79 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c @@ -167,6 +167,13 @@ ldbm_instance_index_config_delete_callback(Slapi_PBlock *pb, Slapi_Entry* e, Sla
returntext[0] = '\0'; *returncode = LDAP_SUCCESS; + + if (slapi_counter_get_value(inst->inst_ref_count) > 0) { + *returncode = LDAP_UNAVAILABLE; + rc = SLAPI_DSE_CALLBACK_ERROR; + } + + *returncode = LDAP_SUCCESS;
slapi_entry_attr_find(e, "cn", &attr); slapi_attr_first_value(attr, &sval); @@ -184,7 +191,6 @@ ldbm_instance_index_config_delete_callback(Slapi_PBlock *pb, Slapi_Entry* e, Sla rc = SLAPI_DSE_CALLBACK_ERROR; } } - return rc; }
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c index f41bd88..34d9bf5 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c @@ -1194,7 +1194,8 @@ ldbm_instance_delete_instance_entry_callback(Slapi_PBlock *pb, Slapi_Entry* entr }
/* check if some online task is happening */ - if (instance_set_busy(inst) != 0) { + if ((instance_set_busy(inst) != 0) || + (slapi_counter_get_value(inst->inst_ref_count) > 0)) { LDAPDebug(LDAP_DEBUG_ANY, "ldbm: '%s' is in the middle of a task. " "Cancel the task or wait for it to finish, " "then try again.\n", instance_name, 0, 0); diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c index 1eaaaae..9cb872a 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c @@ -368,6 +368,14 @@ ldbm_back_modify( Slapi_PBlock *pb ) { goto error_return; } + if (inst->inst_ref_count) { + slapi_counter_increment(inst->inst_ref_count); + } else { + LDAPDebug1Arg(LDAP_DEBUG_ANY, + "ldbm_modify: instance %s does not exist.\n", + inst->inst_name); + goto error_return; + }
/* no need to check the dn syntax as this is a replicated op */ if(!repl_op){ @@ -813,6 +821,9 @@ common_return: cache_unlock_entry( &inst->inst_cache, e); CACHE_RETURN( &inst->inst_cache, &e); } + if (inst->inst_ref_count) { + slapi_counter_decrement(inst->inst_ref_count); + }
/* result code could be used in the bepost plugin functions. */ slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ldap_result_code); diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c index 00e0d61..ef73904 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c @@ -191,6 +191,15 @@ ldbm_back_modrdn( Slapi_PBlock *pb ) return( -1 ); }
+ if (inst->inst_ref_count) { + slapi_counter_increment(inst->inst_ref_count); + } else { + LDAPDebug1Arg(LDAP_DEBUG_ANY, + "ldbm_modrdn: instance %s does not exist.\n", + inst->inst_name); + return( -1 ); + } + /* The dblock serializes writes to the database, * which reduces deadlocking in the db code, * which means that we run faster. @@ -1292,6 +1301,9 @@ common_return: e_in_cache = 1; } } + if (inst->inst_ref_count) { + slapi_counter_decrement(inst->inst_ref_count); + }
moddn_unlock_and_return_entry(be,&e);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_search.c b/ldap/servers/slapd/back-ldbm/ldbm_search.c index 5fbea24..652424e 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_search.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_search.c @@ -169,6 +169,9 @@ ldbm_back_search_cleanup(Slapi_PBlock *pb, slapi_pblock_get( pb, SLAPI_BACKEND, &be ); inst = (ldbm_instance *) be->be_instance_info; CACHE_RETURN(&inst->inst_cache, &e); /* NULL e is handled correctly */ + if (inst->inst_ref_count) { + slapi_counter_decrement(inst->inst_ref_count); + }
if(sort_control!=NULL) { @@ -343,6 +346,7 @@ ldbm_back_search( Slapi_PBlock *pb ) int backend_count = 1; static int print_once = 1; back_txn txn = {NULL}; + int rc = 0;
slapi_pblock_get( pb, SLAPI_BACKEND, &be ); slapi_pblock_get( pb, SLAPI_OPERATION, &operation); @@ -366,6 +370,14 @@ ldbm_back_search( Slapi_PBlock *pb ) "Null target DN", 0, NULL ); return( -1 ); } + if (inst->inst_ref_count) { + slapi_counter_increment(inst->inst_ref_count); + } else { + LDAPDebug1Arg(LDAP_DEBUG_ANY, + "ldbm_search: instance %s does not exist.\n", + inst->inst_name); + return( -1 ); + } base = slapi_sdn_get_dn(basesdn);
/* Initialize the result set structure here because we need to use it during search processing */ @@ -383,9 +395,8 @@ ldbm_back_search( Slapi_PBlock *pb ) sort = slapi_control_present( controls, LDAP_CONTROL_SORTREQUEST, &sort_spec, &is_sorting_critical_orig ); if(sort) { - int r= parse_sort_spec(sort_spec, &sort_control); - if(r!=0) - { + rc = parse_sort_spec(sort_spec, &sort_control); + if (rc) { /* Badly formed SORT control */ return ldbm_back_search_cleanup(pb, li, sort_control, LDAP_PROTOCOL_ERROR, "Sort Control", @@ -401,12 +412,11 @@ ldbm_back_search( Slapi_PBlock *pb ) { if(sort) { - int r = vlv_parse_request_control( be, vlv_spec, &vlv_request_control ); - if(r!=LDAP_SUCCESS) - { + rc = vlv_parse_request_control( be, vlv_spec, &vlv_request_control ); + if (rc != LDAP_SUCCESS) { /* Badly formed VLV control */ return ldbm_back_search_cleanup(pb, li, sort_control, - r, "VLV Control", SLAPI_FAIL_GENERAL, + rc, "VLV Control", SLAPI_FAIL_GENERAL, &vlv_request_control, NULL); } { @@ -421,13 +431,12 @@ ldbm_back_search( Slapi_PBlock *pb ) /* This dn is normalized. */ PR_snprintf(dn,sizeof(dn),"dn: oid=%s,cn=features,cn=config",LDAP_CONTROL_VLVREQUEST); feature= slapi_str2entry(dn,0); - r= plugin_call_acl_plugin (pb, feature, dummyAttrs, NULL, SLAPI_ACL_READ, ACLPLUGIN_ACCESS_DEFAULT, NULL); + rc = plugin_call_acl_plugin (pb, feature, dummyAttrs, NULL, SLAPI_ACL_READ, ACLPLUGIN_ACCESS_DEFAULT, NULL); slapi_entry_free(feature); - if(r!=LDAP_SUCCESS) - { + if (rc != LDAP_SUCCESS) { /* Client isn't allowed to do this. */ return ldbm_back_search_cleanup(pb, li, sort_control, - r, "VLV Control", SLAPI_FAIL_GENERAL, + rc, "VLV Control", SLAPI_FAIL_GENERAL, &vlv_request_control, NULL); } } @@ -650,22 +659,20 @@ ldbm_back_search( Slapi_PBlock *pb ) */ if (virtual_list_view && (NULL != candidates)) { - int r = 0; IDList *idl = NULL; Slapi_Filter *filter = NULL; slapi_pblock_get( pb, SLAPI_SEARCH_FILTER, &filter ); - r = vlv_filter_candidates(be, pb, candidates, basesdn, + rc = vlv_filter_candidates(be, pb, candidates, basesdn, scope, filter, &idl, lookthrough_limit, time_up); - if(r == 0) - { + if (rc == 0) { idl_free(candidates); candidates= idl; } else { return ldbm_back_search_cleanup(pb, li, sort_control, - r, NULL, -1, + rc, NULL, -1, &vlv_request_control, e); } } diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c index 9c024ca..578701a 100644 --- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c +++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c @@ -684,7 +684,8 @@ int ldbm_back_ldif2ldbm( Slapi_PBlock *pb ) }
/* check if an import/restore is already ongoing... */ - if (instance_set_busy(inst) != 0) { + if ((instance_set_busy(inst) != 0) || + (slapi_counter_get_value(inst->inst_ref_count) > 0)) { LDAPDebug(LDAP_DEBUG_ANY, "ldbm: '%s' is already in the middle of " "another task and cannot be disturbed.\n", inst->inst_name, 0, 0); diff --git a/ldap/servers/slapd/back-ldbm/misc.c b/ldap/servers/slapd/back-ldbm/misc.c index a56069b..cfc5e5c 100644 --- a/ldap/servers/slapd/back-ldbm/misc.c +++ b/ldap/servers/slapd/back-ldbm/misc.c @@ -174,7 +174,7 @@ compute_entry_tombstone_rdn(const char *entryrdn, const char *uniqueid) int instance_set_busy(ldbm_instance *inst) { PR_Lock(inst->inst_config_mutex); - if (inst->inst_flags & INST_FLAG_BUSY) { + if (is_instance_busy(inst)) { PR_Unlock(inst->inst_config_mutex); return -1; } @@ -187,7 +187,7 @@ int instance_set_busy(ldbm_instance *inst) int instance_set_busy_and_readonly(ldbm_instance *inst) { PR_Lock(inst->inst_config_mutex); - if (inst->inst_flags & INST_FLAG_BUSY) { + if (is_instance_busy(inst)) { PR_Unlock(inst->inst_config_mutex); return -1; } @@ -280,6 +280,12 @@ is_anyinstance_busy(struct ldbminfo *li) return rval; }
+int +is_instance_busy(ldbm_instance *inst) +{ + return inst->inst_flags & INST_FLAG_BUSY; +} + /* * delete the given file/directory and its sub files/directories */ diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h index 80bf329..daf6d05 100644 --- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h +++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h @@ -150,7 +150,7 @@ int dblayer_database_size(struct ldbminfo *li, unsigned int *size); int dblayer_terminate(struct ldbminfo *li); int dblayer_close_indexes(backend *be); int dblayer_open_file(backend *be, char* indexname, int create, struct attrinfo *ai, DB **ppDB); -int dblayer_close_file(DB *db); +int dblayer_close_file(DB **db); void dblayer_sys_pages(size_t *pagesize, size_t *pages, size_t *procpages, size_t *availpages); int dblayer_is_cachesize_sane(size_t *cachesize); void dblayer_remember_disk_filled(struct ldbminfo *li); @@ -375,6 +375,7 @@ void instance_set_not_busy(ldbm_instance *inst); void allinstance_set_busy(struct ldbminfo *li); void allinstance_set_not_busy(struct ldbminfo *li); int is_anyinstance_busy(struct ldbminfo *li); +int is_instance_busy(ldbm_instance *inst); int ldbm_delete_dirs(char *path); int mkdir_p(char *dir, unsigned int mode); int is_fullpath(char *path); diff --git a/ldap/servers/slapd/back-ldbm/vlv.c b/ldap/servers/slapd/back-ldbm/vlv.c index 7172104..cf68bb3 100644 --- a/ldap/servers/slapd/back-ldbm/vlv.c +++ b/ldap/servers/slapd/back-ldbm/vlv.c @@ -159,7 +159,7 @@ int vlv_DeleteSearchEntry(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr int vlv_DeleteIndexEntry(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* entryAfter, int *returncode, char *returntext, void *arg) { ldbm_instance *inst = (ldbm_instance*)arg; - if (inst && (inst->inst_flags & INST_FLAG_BUSY)) { + if (inst && is_instance_busy(inst)) { LDAPDebug( LDAP_DEBUG_ANY, "Backend instance: '%s' is already in the middle of " "another task and cannot be disturbed.\n",
389-commits@lists.fedoraproject.org