From 340f23990199698cb42b4a4e2686d3c404745800 Mon Sep 17 00:00:00 2001 From: Ludwig Krispenz Date: Aug 13 2019 08:05:34 +0000 Subject: Ticket 50490 objects and memory leaks Bug: There are severalmemory leaks for replication objects Fix: This patch contains a couple of fixes: - The balance of acquire and release for a replica object was incorrect, but the object is allocated at startup or when a replica is added and destroyed at shutdown. In between we know the replica exists and can be accessed directly To ensure that no access was made until it is destroyed the shutdown order was slightly modifed - other objects like RUV or AGMT were also not always correctly balanced, this is corrected - in cl5_api where many types of objects are used, the variable names were changed to bettr indicat to what an object refers - some other leaks, eg in repl5_total_init or op_shared_add were fixed - unused code has been removed Reviewed by: William, Thierry, Mark - thanks --- diff --git a/Makefile.am b/Makefile.am index 2ea1344..b301ae7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -483,7 +483,6 @@ dist_noinst_HEADERS = \ ldap/servers/plugins/replication/repl-session-plugin.h \ ldap/servers/plugins/replication/windows_prot_private.h \ ldap/servers/plugins/replication/repl_helper.h \ - ldap/servers/plugins/replication/repl_objset.h \ ldap/servers/plugins/replication/repl5.h \ ldap/servers/plugins/replication/cl5_test.h \ ldap/servers/plugins/replication/repl5_ruv.h \ @@ -1813,7 +1812,6 @@ libreplication_plugin_la_SOURCES = ldap/servers/plugins/replication/cl5_api.c \ ldap/servers/plugins/replication/repl_ext.c \ ldap/servers/plugins/replication/repl_extop.c \ ldap/servers/plugins/replication/repl_globals.c \ - ldap/servers/plugins/replication/repl_objset.c \ ldap/servers/plugins/replication/repl_opext.c \ ldap/servers/plugins/replication/repl_session_plugin.c \ ldap/servers/plugins/replication/repl5_agmt.c \ diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c index 6b5b28b..a518983 100644 --- a/ldap/servers/plugins/replication/cl5_api.c +++ b/ldap/servers/plugins/replication/cl5_api.c @@ -212,20 +212,20 @@ static void _cl5RemoveThread(void); /* functions that work with individual changelog files */ static int _cl5NewDBFile(const char *replName, const char *replGen, CL5DBFile **dbFile); -static int _cl5DBOpenFile(Object *replica, Object **obj, PRBool checkDups); +static int _cl5DBOpenFile(Replica *replica, Object **obj, PRBool checkDups); static int _cl5DBOpenFileByReplicaName(const char *replName, const char *replGen, Object **obj, PRBool checkDups); static void _cl5DBCloseFile(void **data); static void _cl5DBDeleteFile(Object *obj); static void _cl5DBFileInitialized(Object *obj); -static int _cl5GetDBFile(Object *replica, Object **obj); +static int _cl5GetDBFile(Replica *replica, Object **obj); static int _cl5GetDBFileByReplicaName(const char *replName, const char *replGen, Object **obj); static int _cl5AddDBFile(CL5DBFile *file, Object **obj); static int _cl5CompareDBFile(Object *el1, const void *el2); -static char *_cl5Replica2FileName(Object *replica); +static char *_cl5Replica2FileName(Replica *replica); static char *_cl5MakeFileName(const char *replName, const char *replGen); -static PRBool _cl5FileName2Replica(const char *fileName, Object **replica); +static PRBool _cl5FileName2Replica(const char *fileName, Replica **replica); static int _cl5ExportFile(PRFileDesc *prFile, Object *obj); -static PRBool _cl5ReplicaInList(Object *replica, Object **replicas); +static PRBool _cl5ReplicaInList(Replica *replica, Replica **replicas); /* data storage and retrieval */ static int _cl5Entry2DBData(const CL5Entry *entry, char **data, PRUint32 *len); @@ -234,8 +234,6 @@ static int _cl5WriteOperationTxn(const char *replName, const char *replGen, cons static int _cl5GetFirstEntry(Object *obj, CL5Entry *entry, void **iterator, DB_TXN *txnid); static int _cl5GetNextEntry(CL5Entry *entry, void *iterator); static int _cl5CurrentDeleteEntry(void *iterator); -static PRBool _cl5IsValidIterator(const CL5Iterator *iterator); -static int _cl5GetOperation(Object *replica, slapi_operation_parameters *op); static const char *_cl5OperationType2Str(int type); static int _cl5Str2OperationType(const char *str); static void _cl5WriteString(const char *str, char **buff); @@ -257,7 +255,7 @@ static int32_t _cl5CheckCSNinCL(const ruv_enum_data *element, void *arg); #ifdef FOR_DEBUGGING static PRBool _cl5ValidReplayIterator(const CL5ReplayIterator *iterator); #endif -static int _cl5PositionCursorForReplay(ReplicaId consumerRID, const RUV *consumerRuv, Object *replica, Object *fileObject, CL5ReplayIterator **iterator, int *continue_on_missing); +static int _cl5PositionCursorForReplay(ReplicaId consumerRID, const RUV *consumerRuv, Replica *replica, Object *fileObject, CL5ReplayIterator **iterator, int *continue_on_missing); static int _cl5CheckMissingCSN(const CSN *minCsn, const RUV *supplierRUV, CL5DBFile *file); /* changelog trimming */ @@ -266,8 +264,8 @@ static void _cl5TrimCleanup(void); static int _cl5TrimMain(void *param); static void _cl5DoTrimming(void); static void _cl5CompactDBs(void); -static void _cl5PurgeRID(Object *obj, ReplicaId cleaned_rid); -static int _cl5PurgeGetFirstEntry(Object *obj, CL5Entry *entry, void **iterator, DB_TXN *txnid, int rid, DBT *key); +static void _cl5PurgeRID(Object *file_obj, ReplicaId cleaned_rid); +static int _cl5PurgeGetFirstEntry(Object *file_obj, CL5Entry *entry, void **iterator, DB_TXN *txnid, int rid, DBT *key); static int _cl5PurgeGetNextEntry(CL5Entry *entry, void *iterator, DBT *key); static void _cl5TrimFile(Object *obj, long *numToTrim); static PRBool _cl5CanTrim(time_t time, long *numToTrim); @@ -288,7 +286,7 @@ static int _cl5WriteEntryCount(CL5DBFile *file); /* misc */ static char *_cl5GetHelperEntryKey(int type, char *csnStr); -static Object *_cl5GetReplica(const slapi_operation_parameters *op, const char *replGen); +static Replica *_cl5GetReplica(const slapi_operation_parameters *op, const char *replGen); static int _cl5FileEndsWith(const char *filename, const char *ext); static PRLock *cl5_diskfull_lock = NULL; @@ -553,7 +551,7 @@ cl5Delete(const char *dir) until the file is removed. */ int -cl5DeleteDBSync(Object *replica) +cl5DeleteDBSync(Replica *replica) { Object *obj; int rc; @@ -593,11 +591,9 @@ cl5DeleteDBSync(Object *replica) } slapi_ch_free_string(&filename); } else { - Replica *r = (Replica *)object_get_data(replica); - PR_ASSERT(r); slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, "cl5DeleteDBSync - " "File for replica at (%s) not found\n", - slapi_sdn_get_dn(replica_get_root(r))); + slapi_sdn_get_dn(replica_get_root(replica))); } _cl5RemoveThread(); @@ -619,8 +615,10 @@ int cl5GetUpperBoundRUV(Replica *r, RUV **ruv) { int rc; - Object *r_obj, *file_obj; + Object *file_obj; CL5DBFile *file; + const char *replName; + char *replGen; if (r == NULL || ruv == NULL) { slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, @@ -640,10 +638,10 @@ cl5GetUpperBoundRUV(Replica *r, RUV **ruv) if (rc != CL5_SUCCESS) return rc; - /* create a temporary replica object because of the interface we have */ - r_obj = object_new(r, NULL); - - rc = _cl5GetDBFile(r_obj, &file_obj); + replName = replica_get_name(r); + replGen = replica_get_generation(r); + rc = _cl5GetDBFileByReplicaName(replName, replGen, &file_obj); + slapi_ch_free_string(&replGen); if (rc == CL5_SUCCESS) { file = (CL5DBFile *)object_get_data(file_obj); PR_ASSERT(file && file->maxRUV); @@ -656,8 +654,6 @@ cl5GetUpperBoundRUV(Replica *r, RUV **ruv) "Could not find DB object for replica\n"); } - object_release(r_obj); - _cl5RemoveThread(); return rc; } @@ -677,12 +673,12 @@ cl5GetUpperBoundRUV(Replica *r, RUV **ruv) CL5_MEMORY_ERROR if memory allocation fials. */ int -cl5ExportLDIF(const char *ldifFile, Object **replicas) +cl5ExportLDIF(const char *ldifFile, Replica **replicas) { int i; int rc; PRFileDesc *prFile = NULL; - Object *obj; + Object *file_obj; if (ldifFile == NULL) { slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl, @@ -716,25 +712,21 @@ cl5ExportLDIF(const char *ldifFile, Object **replicas) if (replicas) /* export only selected files */ { for (i = 0; replicas[i]; i++) { - rc = _cl5GetDBFile(replicas[i], &obj); + rc = _cl5GetDBFile(replicas[i], &file_obj); if (rc == CL5_SUCCESS) { - rc = _cl5ExportFile(prFile, obj); - object_release(obj); + rc = _cl5ExportFile(prFile, file_obj); + object_release(file_obj); } else { - Replica *r = (Replica *)object_get_data(replicas[i]); - - PR_ASSERT(r); - slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl, "cl5ExportLDIF - " "Failed to locate changelog file for replica at (%s)\n", - slapi_sdn_get_dn(replica_get_root(r))); + slapi_sdn_get_dn(replica_get_root(replicas[i]))); } } } else /* export all files */ { - for (obj = objset_first_obj(s_cl5Desc.dbFiles); obj; - obj = objset_next_obj(s_cl5Desc.dbFiles, obj)) { - rc = _cl5ExportFile(prFile, obj); + for (file_obj = objset_first_obj(s_cl5Desc.dbFiles); file_obj; + file_obj = objset_next_obj(s_cl5Desc.dbFiles, file_obj)) { + rc = _cl5ExportFile(prFile, file_obj); } } @@ -766,7 +758,7 @@ done:; CL5_MEMORY_ERROR if memory allocation fials. */ int -cl5ImportLDIF(const char *clDir, const char *ldifFile, Object **replicas) +cl5ImportLDIF(const char *clDir, const char *ldifFile, Replica **replicas) { LDIFFP *file = NULL; int buflen = 0; @@ -774,10 +766,9 @@ cl5ImportLDIF(const char *clDir, const char *ldifFile, Object **replicas) int rc; char *buff = NULL; slapi_operation_parameters op; - Object *prim_replica_obj = NULL; - Object *replica_obj = NULL; - Object *file_obj = NULL; Replica *prim_replica = NULL; + Replica *replica = NULL; + Object *file_obj = NULL; char *replGen = NULL; CL5DBFile *dbfile = NULL; struct berval **purgevals = NULL; @@ -807,14 +798,13 @@ cl5ImportLDIF(const char *clDir, const char *ldifFile, Object **replicas) return CL5_BAD_DATA; } - prim_replica_obj = replicas[0]; - if (NULL == prim_replica_obj) { + prim_replica = replicas[0]; + if (NULL == prim_replica) { /* Never happens for now. (see replica_execute_ldif2cl_task) */ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl, "cl5ImportLDIF - empty replica list\n"); return CL5_BAD_DATA; } - prim_replica = (Replica *)object_get_data(prim_replica_obj); /* make sure that nobody change changelog state while import is in progress */ slapi_rwlock_wrlock(s_cl5Desc.stLock); @@ -918,8 +908,8 @@ cl5ImportLDIF(const char *clDir, const char *ldifFile, Object **replicas) slapi_ch_free_string(&buff); buflen = 0; /* if we perform selective import, check if the operation should be wriiten to changelog */ - replica_obj = _cl5GetReplica(&op, replGen); - if (replica_obj == NULL) { + replica = _cl5GetReplica(&op, replGen); + if (replica == NULL) { /* * changetype: delete * replgen: 4d13a124000000010000 @@ -943,9 +933,9 @@ cl5ImportLDIF(const char *clDir, const char *ldifFile, Object **replicas) goto next; } - if (!replicas || _cl5ReplicaInList(replica_obj, replicas)) { + if (!replicas || _cl5ReplicaInList(replica, replicas)) { /* write operation creates the file if it does not exist */ - rc = _cl5WriteOperation(replica_get_name((Replica *)object_get_data(replica_obj)), + rc = _cl5WriteOperation(replica_get_name(replica), replGen, &op, 1); if (rc != CL5_SUCCESS) { slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl, @@ -953,7 +943,6 @@ cl5ImportLDIF(const char *clDir, const char *ldifFile, Object **replicas) "Failed to write operation to the changelog: " "type: %lu, dn: %s\n", op.operation_type, REPL_GET_DN(&op.target_address)); - object_release(replica_obj); slapi_ch_free_string(&replGen); operation_parameters_done(&op); goto done; @@ -961,9 +950,6 @@ cl5ImportLDIF(const char *clDir, const char *ldifFile, Object **replicas) entryCount++; } next: - if (replica_obj) { - object_release(replica_obj); - } slapi_ch_free_string(&replGen); operation_parameters_done(&op); } @@ -1089,147 +1075,6 @@ cl5ConfigTrimming(int maxEntries, const char *maxAge, int compactInterval, int t return CL5_SUCCESS; } -/* Name: cl5GetOperation - Description: retireves operation specified by its csn and databaseid - Parameters: op - must contain csn and databaseid; the rest of data is - filled if function is successfull - Return: CL5_SUCCESS if function is successfull; - CL5_BAD_DATA if invalid op is passed; - CL5_BAD_STATE if db has not been initialized; - CL5_NOTFOUND if entry was not found; - CL5_DB_ERROR if any other db error occured; - CL5_BADFORMAT if db data format does not match entry format. - */ -int -cl5GetOperation(Object *replica, slapi_operation_parameters *op) -{ - int rc; - char *agmt_name; - - agmt_name = get_thread_private_agmtname(); - - if (replica == NULL) { - slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, "cl5GetOperation - NULL replica\n"); - return CL5_BAD_DATA; - } - - if (op == NULL) { - slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, "cl5GetOperation - NULL operation\n"); - return CL5_BAD_DATA; - } - - if (op->csn == NULL) { - slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, "%s: cl5GetOperation - operation contains no CSN\n", agmt_name); - return CL5_BAD_DATA; - } - - if (s_cl5Desc.dbState == CL5_STATE_NONE) { - slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, - "cl5GetOperation - %s - Changelog is not initialized\n", agmt_name); - return CL5_BAD_STATE; - } - - /* make sure that changelog is open while operation is in progress */ - rc = _cl5AddThread(); - if (rc != CL5_SUCCESS) - return rc; - - rc = _cl5GetOperation(replica, op); - - _cl5RemoveThread(); - - return rc; -} - -/* Name: cl5GetFirstOperation - Description: retrieves first operation for a particular database - replica - replica for which the operation should be retrieved. - Parameters: op - buffer to store the operation; - iterator - to be passed to the call to cl5GetNextOperation - Return: CL5_SUCCESS, if successful - CL5_BADDATA, if operation is NULL - CL5_BAD_STATE, if changelog is not open - CL5_DB_ERROR, if db call fails - */ -int -cl5GetFirstOperation(Object *replica, slapi_operation_parameters *op, void **iterator) -{ - int rc; - CL5Entry entry; - Object *obj; - char *agmt_name; - - if (replica == NULL || op == NULL || iterator == NULL) { - slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, - "cl5GetFirstOperation - Invalid argument\n"); - return CL5_BAD_DATA; - } - - *iterator = NULL; - - if (s_cl5Desc.dbState == CL5_STATE_NONE) { - agmt_name = get_thread_private_agmtname(); - slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, - "cl5GetFirstOperation - %s - Changelog is not initialized\n", agmt_name); - return CL5_BAD_STATE; - } - - /* make sure that changelog stays open while operation is in progress */ - rc = _cl5AddThread(); - if (rc != CL5_SUCCESS) - return rc; - - rc = _cl5GetDBFile(replica, &obj); - if (rc != CL5_SUCCESS) { - _cl5RemoveThread(); - return rc; - } - - entry.op = op; - /* Callers of this function should cl5_operation_parameters_done(op) */ - rc = _cl5GetFirstEntry(obj, &entry, iterator, NULL); - object_release(obj); - - _cl5RemoveThread(); - - return rc; -} - -/* Name: cl5GetNextOperation - Description: retrieves the next op from the changelog as defined by the iterator; - changelog must be open. - Parameters: op - returned operation, if function is successful - iterator - in: identifies op to retrieve; out: identifies next op - Return: CL5_SUCCESS, if successful - CL5_BADDATA, if op is NULL - CL5_BAD_STATE, if changelog is not open - CL5_NOTFOUND, empty changelog - CL5_DB_ERROR, if db call fails - */ -int -cl5GetNextOperation(slapi_operation_parameters *op, void *iterator) -{ - CL5Entry entry; - - if (op == NULL || iterator == NULL || !_cl5IsValidIterator(iterator)) { - slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, - "cl5GetNextOperation - Invalid argument\n"); - return CL5_BAD_DATA; - } - - if (s_cl5Desc.dbState != CL5_STATE_OPEN) { - slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, - "cl5GetNextOperation - Changelog is not open\n"); - return CL5_BAD_STATE; - } - - /* we don't need to increment thread count since cl5GetFirstOperation - locked the file through which we are iterating */ - entry.op = op; - /* Callers of this function should cl5_operation_parameters_done(op) */ - return _cl5GetNextEntry(&entry, iterator); -} - /* Name: cl5DestroyIterator Description: destroys iterator once iteration through changelog is done Parameters: iterator - iterator to destroy @@ -1371,10 +1216,10 @@ int cl5CreateReplayIteratorEx(Private_Repl_Protocol *prp, const RUV *consumerRuv, CL5ReplayIterator **iterator, ReplicaId consumerRID) { int rc; - Object *replica; - Object *obj = NULL; + Replica *replica; + Object *file_obj = NULL; - replica = prp->replica_object; + replica = prp->replica; if (replica == NULL || consumerRuv == NULL || iterator == NULL) { slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, "cl5CreateReplayIteratorEx - Invalid parameter\n"); @@ -1395,21 +1240,21 @@ cl5CreateReplayIteratorEx(Private_Repl_Protocol *prp, const RUV *consumerRuv, CL return rc; - rc = _cl5GetDBFile(replica, &obj); - if (rc == CL5_SUCCESS && obj) { + rc = _cl5GetDBFile(replica, &file_obj); + if (rc == CL5_SUCCESS && file_obj) { /* iterate through the ruv in csn order to find first master for which we can replay changes */ - rc = _cl5PositionCursorForReplay(consumerRID, consumerRuv, replica, obj, iterator, NULL); + rc = _cl5PositionCursorForReplay(consumerRID, consumerRuv, replica, file_obj, iterator, NULL); } else { slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, "cl5CreateReplayIteratorEx - Could not find DB object for replica\n"); } if (rc != CL5_SUCCESS) { - if (obj) - object_release(obj); - + if (file_obj) { + object_release(file_obj); + } /* release the thread */ _cl5RemoveThread(); } @@ -1428,10 +1273,10 @@ cl5CreateReplayIterator(Private_Repl_Protocol *prp, const RUV *consumerRuv, CL5R return cl5CreateReplayIteratorEx(prp,consumerRuv,iterator,consumerRID); */ int rc; - Object *replica; - Object *obj = NULL; + Replica *replica; + Object *file_obj = NULL; - replica = prp->replica_object; + replica = prp->replica; if (replica == NULL || consumerRuv == NULL || iterator == NULL) { slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, "cl5CreateReplayIterator - Invalid parameter\n"); @@ -1452,14 +1297,14 @@ cl5CreateReplayIterator(Private_Repl_Protocol *prp, const RUV *consumerRuv, CL5R return rc; - rc = _cl5GetDBFile(replica, &obj); - if (rc == CL5_SUCCESS && obj) { + rc = _cl5GetDBFile(replica, &file_obj); + if (rc == CL5_SUCCESS && file_obj) { /* iterate through the ruv in csn order to find first master for which we can replay changes */ ReplicaId consumerRID = agmt_get_consumer_rid(prp->agmt, prp->conn); int continue_on_missing = agmt_get_ignoremissing(prp->agmt); int save_cont_miss = continue_on_missing; - rc = _cl5PositionCursorForReplay(consumerRID, consumerRuv, replica, obj, iterator, &continue_on_missing); + rc = _cl5PositionCursorForReplay(consumerRID, consumerRuv, replica, file_obj, iterator, &continue_on_missing); if (save_cont_miss == 1 && continue_on_missing == 0) { /* the option to continue once on a missing csn was used, rest */ agmt_set_ignoremissing(prp->agmt, 0); @@ -1470,8 +1315,8 @@ cl5CreateReplayIterator(Private_Repl_Protocol *prp, const RUV *consumerRuv, CL5R } if (rc != CL5_SUCCESS) { - if (obj) - object_release(obj); + if (file_obj) + object_release(file_obj); /* release the thread */ _cl5RemoveThread(); @@ -1645,9 +1490,9 @@ cl5Exist(const char *clDir) */ int -cl5GetOperationCount(Object *replica) +cl5GetOperationCount(Replica *replica) { - Object *obj; + Object *file_obj; CL5DBFile *file; int count = 0; int rc; @@ -1665,25 +1510,25 @@ cl5GetOperationCount(Object *replica) if (replica == NULL) /* compute total entry count */ { - obj = objset_first_obj(s_cl5Desc.dbFiles); - while (obj) { - file = (CL5DBFile *)object_get_data(obj); + file_obj = objset_first_obj(s_cl5Desc.dbFiles); + while (file_obj) { + file = (CL5DBFile *)object_get_data(file_obj); PR_ASSERT(file); count += file->entryCount; - obj = objset_next_obj(s_cl5Desc.dbFiles, obj); + file_obj = objset_next_obj(s_cl5Desc.dbFiles, file_obj); } } else /* return count for particular db */ { /* select correct db file */ - rc = _cl5GetDBFile(replica, &obj); + rc = _cl5GetDBFile(replica, &file_obj); if (rc == CL5_SUCCESS) { - file = (CL5DBFile *)object_get_data(obj); + file = (CL5DBFile *)object_get_data(file_obj); PR_ASSERT(file); count = file->entryCount; slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, - "cl5GetOperationCount - Found DB object %p\n", obj); - object_release(obj); + "cl5GetOperationCount - Found DB object %p\n", file_obj); + object_release(file_obj); } else { slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, "cl5GetOperationCount - Could not get DB object for replica\n"); @@ -1875,7 +1720,7 @@ _cl5DBOpen() PRDir *dir; PRDirEntry *entry = NULL; int rc = -1; /* initialize to failure */ - Object *replica; + Replica *replica; int count = 0; /* create lock that guarantees that each file is only added once to the list */ @@ -1910,8 +1755,6 @@ _cl5DBOpen() entry->name); return rc; } - - object_release(replica); count++; } else /* there is no matching replica for the file - remove */ { @@ -3291,7 +3134,7 @@ _cl5TrimMain(void *param __attribute__((unused))) static void _cl5DoTrimming(void) { - Object *obj; + Object *file_obj; long numToTrim; PR_Lock(s_cl5Desc.dbTrim.lock); @@ -3302,14 +3145,14 @@ _cl5DoTrimming(void) * might have to fix that by, for example, randomizing the starting * point. */ - obj = objset_first_obj(s_cl5Desc.dbFiles); - while (obj && _cl5CanTrim((time_t)0, &numToTrim)) { - _cl5TrimFile(obj, &numToTrim); - obj = objset_next_obj(s_cl5Desc.dbFiles, obj); + file_obj = objset_first_obj(s_cl5Desc.dbFiles); + while (file_obj && _cl5CanTrim((time_t)0, &numToTrim)) { + _cl5TrimFile(file_obj, &numToTrim); + file_obj = objset_next_obj(s_cl5Desc.dbFiles, file_obj); } - if (obj) - object_release(obj); + if (file_obj) + object_release(file_obj); PR_Unlock(s_cl5Desc.dbTrim.lock); @@ -3329,15 +3172,15 @@ _cl5DoPurging(cleanruv_purge_data *purge_data) const char *replName = purge_data->replName; char *replGen = purge_data->replGen; char *fileName; - Object *obj; + Object *file_obj; PR_Lock(s_cl5Desc.dbTrim.lock); fileName = _cl5MakeFileName(replName, replGen); - obj = objset_find(s_cl5Desc.dbFiles, _cl5CompareDBFile, fileName); - if (obj) { + file_obj = objset_find(s_cl5Desc.dbFiles, _cl5CompareDBFile, fileName); + if (file_obj) { /* We found our changelog, now purge it */ - _cl5PurgeRID(obj, rid); - object_release(obj); + _cl5PurgeRID(file_obj, rid); + object_release(file_obj); slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, "_cl5DoPurging - Purged rid (%d) from suffix (%s)\n", rid, slapi_sdn_get_dn(suffix_sdn)); @@ -3420,7 +3263,7 @@ bail: * starting point. */ static int -_cl5PurgeGetFirstEntry(Object *obj, CL5Entry *entry, void **iterator, DB_TXN *txnid, int rid, DBT *key) +_cl5PurgeGetFirstEntry(Object *file_obj, CL5Entry *entry, void **iterator, DB_TXN *txnid, int rid, DBT *key) { DBC *cursor = NULL; DBT data = {0}; @@ -3428,7 +3271,7 @@ _cl5PurgeGetFirstEntry(Object *obj, CL5Entry *entry, void **iterator, DB_TXN *tx CL5DBFile *file; int rc; - file = (CL5DBFile *)object_get_data(obj); + file = (CL5DBFile *)object_get_data(file_obj); /* create cursor */ rc = file->db->cursor(file->db, txnid, &cursor, 0); @@ -3460,8 +3303,8 @@ _cl5PurgeGetFirstEntry(Object *obj, CL5Entry *entry, void **iterator, DB_TXN *tx it = (CL5Iterator *)slapi_ch_malloc(sizeof(CL5Iterator)); it->cursor = cursor; - object_acquire(obj); - it->file = obj; + object_acquire(file_obj); + it->file = file_obj; *(CL5Iterator **)iterator = it; return CL5_SUCCESS; @@ -3563,7 +3406,7 @@ _cl5PurgeGetNextEntry(CL5Entry *entry, void *iterator, DBT *key) * beginning for each new iteration. */ static void -_cl5PurgeRID(Object *obj, ReplicaId cleaned_rid) +_cl5PurgeRID(Object *file_obj, ReplicaId cleaned_rid) { slapi_operation_parameters op = {0}; ReplicaId csn_rid; @@ -3580,7 +3423,7 @@ _cl5PurgeRID(Object *obj, ReplicaId cleaned_rid) int finished = 0; int rc = 0; - PR_ASSERT(obj); + PR_ASSERT(file_obj); entry.op = &op; /* @@ -3608,7 +3451,7 @@ _cl5PurgeRID(Object *obj, ReplicaId cleaned_rid) /* * Check every changelog entry for the cleaned rid */ - rc = _cl5PurgeGetFirstEntry(obj, &entry, &iterator, txnid, first_pass ? 0 : cleaned_rid, &key); + rc = _cl5PurgeGetFirstEntry(file_obj, &entry, &iterator, txnid, first_pass ? 0 : cleaned_rid, &key); first_pass = 0; while (rc == CL5_SUCCESS && !slapi_is_shutting_down()) { /* @@ -4220,7 +4063,6 @@ _cl5GetRUV2Purge2(Object *fileObj, RUV **ruv) { int rc = CL5_SUCCESS; CL5DBFile *dbFile; - Object *rObj = NULL; Replica *r = NULL; Object *agmtObj = NULL; Repl_Agmt *agmt; @@ -4238,17 +4080,13 @@ _cl5GetRUV2Purge2(Object *fileObj, RUV **ruv) dbFile = (CL5DBFile *)object_get_data(fileObj); PR_ASSERT(dbFile); - rObj = replica_get_by_name(dbFile->replName); - PR_ASSERT(rObj); + r = replica_get_by_name(dbFile->replName); - if (!rObj) { + if (!r) { rc = CL5_NOTFOUND; goto done; } - r = (Replica *)object_get_data(rObj); - PR_ASSERT(r); - /* We start with this replica's RUV. See note in _cl5DoTrimming */ supRUVObj = replica_get_ruv(r); PR_ASSERT(supRUVObj); @@ -4295,9 +4133,6 @@ _cl5GetRUV2Purge2(Object *fileObj, RUV **ruv) csn_free(&csn); } done: - if (rObj) - object_release(rObj); - if (rc != CL5_SUCCESS && ruv) ruv_destroy(ruv); @@ -4886,7 +4721,7 @@ _cl5WriteOperation(const char *replName, const char *replGen, const slapi_operat } static int -_cl5GetFirstEntry(Object *obj, CL5Entry *entry, void **iterator, DB_TXN *txnid) +_cl5GetFirstEntry(Object *file_obj, CL5Entry *entry, void **iterator, DB_TXN *txnid) { int rc; DBC *cursor = NULL; @@ -4894,9 +4729,9 @@ _cl5GetFirstEntry(Object *obj, CL5Entry *entry, void **iterator, DB_TXN *txnid) CL5Iterator *it; CL5DBFile *file; - PR_ASSERT(obj && entry && iterator); + PR_ASSERT(file_obj && entry && iterator); - file = (CL5DBFile *)object_get_data(obj); + file = (CL5DBFile *)object_get_data(file_obj); PR_ASSERT(file); /* create cursor */ rc = file->db->cursor(file->db, txnid, &cursor, 0); @@ -4929,8 +4764,8 @@ _cl5GetFirstEntry(Object *obj, CL5Entry *entry, void **iterator, DB_TXN *txnid) it = (CL5Iterator *)slapi_ch_malloc(sizeof(CL5Iterator)); it->cursor = cursor; - object_acquire(obj); - it->file = obj; + object_acquire(file_obj); + it->file = file_obj; *(CL5Iterator **)iterator = it; return CL5_SUCCESS; @@ -5066,79 +4901,6 @@ _cl5CurrentDeleteEntry(void *iterator) } } -static PRBool -_cl5IsValidIterator(const CL5Iterator *iterator) -{ - return (iterator && iterator->cursor && iterator->file); -} - -static int -_cl5GetOperation(Object *replica, slapi_operation_parameters *op) -{ - int rc; - DBT key = {0}, data = {0}; - CL5DBFile *file; - CL5Entry entry; - Object *obj = NULL; - char csnStr[CSN_STRSIZE]; - - rc = _cl5GetDBFile(replica, &obj); - if (rc != CL5_SUCCESS || !obj) { - goto done; - } - - file = (CL5DBFile *)object_get_data(obj); - PR_ASSERT(file); - - /* construct the key */ - key.data = csn_as_string(op->csn, PR_FALSE, csnStr); - key.size = CSN_STRSIZE; - - data.flags = DB_DBT_MALLOC; - - rc = file->db->get(file->db, NULL /*txn*/, &key, &data, 0); - switch (rc) { - case 0: - entry.op = op; - /* Callers of this function should cl5_operation_parameters_done(op) */ - rc = cl5DBData2Entry(data.data, data.size, &entry); - if (rc == CL5_SUCCESS) { - slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, - "_cl5GetOperation - Successfully retrieved operation with csn (%s)\n", - csnStr); - } else { - slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, - "_cl5GetOperation - Failed to convert db data to operation;" - " csn - %s\n", - csnStr); - } - goto done; - - case DB_NOTFOUND: - slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, - "_cl5GetOperation - Operation for csn (%s) is not found in db that should contain dn (%s)\n", - csnStr, REPL_GET_DN(&op->target_address)); - rc = CL5_NOTFOUND; - goto done; - - default: - slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, - "_cl5GetOperation - Failed to get entry for csn (%s); " - "db error - %d %s\n", - csnStr, rc, db_strerror(rc)); - rc = CL5_DB_ERROR; - goto done; - } - -done: - if (obj) - object_release(obj); - - slapi_ch_free(&(data.data)); - - return rc; -} - PRBool cl5HelperEntry(const char *csnstr, CSN *csnp) { @@ -5191,7 +4953,7 @@ struct replica_hash_entry static int -_cl5PositionCursorForReplay(ReplicaId consumerRID, const RUV *consumerRuv, Object *replica, Object *fileObj, CL5ReplayIterator **iterator, int *continue_on_missing) +_cl5PositionCursorForReplay(ReplicaId consumerRID, const RUV *consumerRuv, Replica *replica, Object *fileObj, CL5ReplayIterator **iterator, int *continue_on_missing) { CLC_Buffer *clcache = NULL; CL5DBFile *file; @@ -5209,7 +4971,7 @@ _cl5PositionCursorForReplay(ReplicaId consumerRID, const RUV *consumerRuv, Objec file = (CL5DBFile *)object_get_data(fileObj); /* get supplier's RUV */ - supplierRuvObj = replica_get_ruv((Replica *)object_get_data(replica)); + supplierRuvObj = replica_get_ruv(replica); PR_ASSERT(supplierRuvObj); if (!supplierRuvObj) { @@ -5547,9 +5309,8 @@ _cl5CheckMissingCSN(const CSN *csn, const RUV *supplierRuv, CL5DBFile *file) /* file name format : _db{2,3,...} */ static PRBool -_cl5FileName2Replica(const char *file_name, Object **replica) +_cl5FileName2Replica(const char *file_name, Replica **replica) { - Replica *r; char *repl_name, *file_gen, *repl_gen; int len; @@ -5578,18 +5339,15 @@ _cl5FileName2Replica(const char *file_name, Object **replica) file_gen[len - extlen - 1] = '\0'; *replica = replica_get_by_name(repl_name); if (*replica) { - /* check that generation matches the one in replica object */ - r = (Replica *)object_get_data(*replica); - repl_gen = replica_get_generation(r); + repl_gen = replica_get_generation(*replica); PR_ASSERT(repl_gen); if (strcmp(file_gen, repl_gen) != 0) { slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, "_cl5FileName2Replica - " "Replica generation mismatch for replica at (%s), " "file generation %s, new replica generation %s\n", - slapi_sdn_get_dn(replica_get_root(r)), file_gen, repl_gen); + slapi_sdn_get_dn(replica_get_root(*replica)), file_gen, repl_gen); - object_release(*replica); *replica = NULL; } slapi_ch_free((void **)&repl_gen); @@ -5609,15 +5367,11 @@ _cl5FileName2Replica(const char *file_name, Object **replica) /* file name format : _db{2,3} */ static char * -_cl5Replica2FileName(Object *replica) +_cl5Replica2FileName(Replica *r) { const char *replName; char *replGen, *fileName; - Replica *r; - PR_ASSERT(replica); - - r = (Replica *)object_get_data(replica); PR_ASSERT(r); replName = replica_get_name(r); @@ -5642,19 +5396,17 @@ _cl5MakeFileName(const char *replName, const char *replGen) /* open file that corresponds to a particular database */ static int -_cl5DBOpenFile(Object *replica, Object **obj, PRBool checkDups) +_cl5DBOpenFile(Replica *replica, Object **obj, PRBool checkDups) { int rc; const char *replName; char *replGen; - Replica *r; PR_ASSERT(replica); - r = (Replica *)object_get_data(replica); - replName = replica_get_name(r); + replName = replica_get_name(replica); PR_ASSERT(replName); - replGen = replica_get_generation(r); + replGen = replica_get_generation(replica); PR_ASSERT(replGen); rc = _cl5DBOpenFileByReplicaName(replName, replGen, obj, checkDups); @@ -5938,7 +5690,7 @@ _cl5DBCloseFile(void **data) } static int -_cl5GetDBFile(Object *replica, Object **obj) +_cl5GetDBFile(Replica *replica, Object **obj) { char *fileName; @@ -5988,37 +5740,37 @@ _cl5GetDBFileByReplicaName(const char *replName, const char *replGen, Object **o } static void -_cl5DBDeleteFile(Object *obj) +_cl5DBDeleteFile(Object *file_obj) { CL5DBFile *file; int rc = 0; - PR_ASSERT(obj); + PR_ASSERT(file_obj); - file = (CL5DBFile *)object_get_data(obj); + file = (CL5DBFile *)object_get_data(file_obj); PR_ASSERT(file); file->flags |= DB_FILE_DELETED; - rc = objset_remove_obj(s_cl5Desc.dbFiles, obj); + rc = objset_remove_obj(s_cl5Desc.dbFiles, file_obj); if (rc != OBJSET_SUCCESS) { slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, "_cl5DBDeleteFile - " "could not find DB object %p\n", - obj); + file_obj); } else { slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, "_cl5DBDeleteFile - " "removed DB object %p\n", - obj); + file_obj); } - object_release(obj); + object_release(file_obj); } static void -_cl5DBFileInitialized(Object *obj) +_cl5DBFileInitialized(Object *file_obj) { CL5DBFile *file; - PR_ASSERT(obj); + PR_ASSERT(file_obj); - file = (CL5DBFile *)object_get_data(obj); + file = (CL5DBFile *)object_get_data(file_obj); PR_ASSERT(file); file->flags |= DB_FILE_INIT; } @@ -6123,13 +5875,15 @@ _cl5ExportFile(PRFileDesc *prFile, Object *obj) } static PRBool -_cl5ReplicaInList(Object *replica, Object **replicas) +_cl5ReplicaInList(Replica *replica, Replica **replicas) { int i; PR_ASSERT(replica && replicas); /* ONREPL I think it should be sufficient to just compare replica pointers */ + /* LK not sure about this, but it is only used for changlog import for + * multiple changelogs, shozld probably be deprecated anyway */ for (i = 0; replicas[i]; i++) { if (replica == replicas[i]) return PR_TRUE; @@ -6153,11 +5907,10 @@ _cl5GetHelperEntryKey(int type, char *csnStr) return rt; } -static Object * +static Replica * _cl5GetReplica(const slapi_operation_parameters *op, const char *replGen) { Slapi_DN *sdn; - Object *replObj; Replica *replica; char *newGen; @@ -6165,22 +5918,19 @@ _cl5GetReplica(const slapi_operation_parameters *op, const char *replGen) sdn = op->target_address.sdn; - replObj = replica_get_replica_from_dn(sdn); - if (replObj) { + replica = replica_get_replica_from_dn(sdn); + if (replica) { /* check to see if replica generation has not change */ - replica = (Replica *)object_get_data(replObj); - PR_ASSERT(replica); newGen = replica_get_generation(replica); PR_ASSERT(newGen); if (strcmp(replGen, newGen) != 0) { - object_release(replObj); - replObj = NULL; + replica = NULL; } slapi_ch_free((void **)&newGen); } - return replObj; + return replica; } int diff --git a/ldap/servers/plugins/replication/cl5_api.h b/ldap/servers/plugins/replication/cl5_api.h index 4331fdb..302af97 100644 --- a/ldap/servers/plugins/replication/cl5_api.h +++ b/ldap/servers/plugins/replication/cl5_api.h @@ -173,7 +173,7 @@ int cl5Delete(const char *dir); Description: The same as cl5DeleteDB except the function does not return until the file is removed. */ -int cl5DeleteDBSync(Object *replica); +int cl5DeleteDBSync(Replica *replica); /* Name: cl5GetUpperBoundRUV Description: retrieves vector that represent the upper bound of changes @@ -202,7 +202,7 @@ int cl5GetUpperBoundRUV(Replica *r, RUV **ruv); CL5_SYSTEM_ERROR if NSPR call fails; CL5_MEMORY_ERROR if memory allocation fails. */ -int cl5ExportLDIF(const char *ldifFile, Object **replicas); +int cl5ExportLDIF(const char *ldifFile, Replica **replicas); /* Name: cl5ImportLDIF Description: imports ldif file into changelog; changelog must be in the closed state @@ -217,7 +217,7 @@ int cl5ExportLDIF(const char *ldifFile, Object **replicas); CL5_SYSTEM_ERROR if NSPR call fails; CL5_MEMORY_ERROR if memory allocation fails. */ -int cl5ImportLDIF(const char *clDir, const char *ldifFile, Object **replicas); +int cl5ImportLDIF(const char *clDir, const char *ldifFile, Replica **replicas); /* Name: cl5GetState Description: returns database state @@ -238,52 +238,6 @@ int cl5GetState(void); */ int cl5ConfigTrimming(int maxEntries, const char *maxAge, int compactInterval, int trimInterval); -/* Name: cl5GetOperation - Description: retrieves operation specified by its csn and databaseid - Parameters: op - must contain csn and databaseid; the rest of data is - filled if function is successful - Return: CL5_SUCCESS if function is successful; - CL5_BAD_DATA if invalid op is passed; - CL5_BAD_STATE if db has not been initialized; - CL5_NOTFOUND if entry was not found; - CL5_DB_ERROR if any other db error occurred; - CL5_BADFORMAT if db data format does not match entry format. - */ -int cl5GetOperation(Object *replica, slapi_operation_parameters *op); - -/* Name: cl5GetFirstOperation - Description: retrieves first operation for a particular database - replica - replica for which the operation should be retrieved. - Parameters: op - buffer to store the operation; - iterator - to be passed to the call to cl5GetNextOperation - Return: CL5_SUCCESS, if successful - CL5_BADDATA, if operation is NULL - CL5_BAD_STATE, if changelog is not open - CL5_DB_ERROR, if db call fails - */ -int cl5GetFirstOperation(Object *replica, slapi_operation_parameters *op, void **iterator); - -/* Name: cl5GetNextOperation - Description: retrieves the next op from the changelog as defined by the iterator - Parameters: replica - replica for which the operation should be retrieved. - op - returned operation, if function is successful - iterator - in: identifies op to retrieve; out: identifies next op - Return: CL5_SUCCESS, if successful - CL5_BADDATA, if invalid parameter is supplied - CL5_BAD_STATE, if changelog is not open - CL5_NOTFOUND, empty changelog - CL5_DB_ERROR, if db call fails - */ -int cl5GetNextOperation(slapi_operation_parameters *op, void *iterator); - -/* Name: cl5DestroyIterator - Description: destroys iterator once iteration through changelog is done - Parameters: iterator - iterator to destroy - Return: CL5_SUCCESS, if successful - CL5_BADDATA, if invalid parameters is supplied - CL5_BAD_STATE, if changelog is not open - CL5_DB_ERROR, if db call fails - */ void cl5DestroyIterator(void *iterator); /* Name: cl5WriteOperationTxn @@ -399,7 +353,7 @@ PRBool cl5Exist(const char *clDir); Return: number of entries in the changelog */ -int cl5GetOperationCount(Object *replica); +int cl5GetOperationCount(Replica *replica); /* Name: cl5_operation_parameters_done Description: frees all parameters that are not freed by operation_parameters_done diff --git a/ldap/servers/plugins/replication/cl5_test.c b/ldap/servers/plugins/replication/cl5_test.c index 940ee2d..d665665 100644 --- a/ldap/servers/plugins/replication/cl5_test.c +++ b/ldap/servers/plugins/replication/cl5_test.c @@ -144,7 +144,6 @@ testBackupRestore() static void testIteration() { - Object *r_obj; Slapi_DN *r_root; Replica *r; char *replGen; @@ -158,9 +157,9 @@ testIteration() /* get replica object */ r_root = slapi_sdn_new_dn_byval(REPLICA_ROOT); - r_obj = replica_get_replica_from_dn(r_root); + r = replica_get_replica_from_dn(r_root); slapi_sdn_free(&r_root); - if (r_obj == NULL) { + if (r == NULL) { slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl, "replica is not configured for (%s)\n", REPLICA_ROOT); return; @@ -169,13 +168,11 @@ testIteration() slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl, "Starting first iteration pass ...\n"); /* configure empty consumer ruv */ - r = (Replica *)object_get_data(r_obj); - PR_ASSERT(r); replGen = replica_get_generation(r); ruv_init_new(replGen, 0, NULL, &ruv); /* create replay iterator */ - rc = cl5CreateReplayIterator(r_obj, ruv, &it); + rc = cl5CreateReplayIterator(r, ruv, &it); if (it) { i = 0; while ((rc = cl5GetNextOperationToReplay(it, &op)) == CL5_SUCCESS) { @@ -205,7 +202,7 @@ testIteration() populateChangelogOp(); /* create replay iterator */ - rc = cl5CreateReplayIterator(r_obj, ruv, &it); + rc = cl5CreateReplayIterator(r, ruv, &it); if (it) { i = 0; while ((rc = cl5GetNextOperationToReplay(it, &op)) == CL5_SUCCESS) { @@ -235,7 +232,7 @@ testIteration() populateChangelogOp(); /* create replay iterator */ - rc = cl5CreateReplayIterator(r_obj, ruv, &it); + rc = cl5CreateReplayIterator(r, ruv, &it); if (it) { i = 0; while ((rc = cl5GetNextOperationToReplay(it, &op)) == CL5_SUCCESS) { @@ -263,7 +260,6 @@ testIteration() slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl, "Iteration test is complete\n"); ruv_destroy(&ruv); - object_release(r_obj); slapi_ch_free((void **)&replGen); } diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h index 9d25f23..873dd8a 100644 --- a/ldap/servers/plugins/replication/repl5.h +++ b/ldap/servers/plugins/replication/repl5.h @@ -521,7 +521,7 @@ void consumer_operation_extension_destructor(void *ext, void *object, void *pare typedef struct consumer_connection_extension { int repl_protocol_version; /* the replication protocol version number the supplier is talking. */ - void *replica_acquired; /* Object* for replica */ + Replica *replica_acquired; /* replica */ void *supplier_ruv; /* RUV* */ int isreplicationsession; Slapi_Connection *connection; @@ -541,6 +541,7 @@ int consumer_connection_extension_relinquish_exclusive_access(void *conn, uint64 typedef struct multimaster_mtnode_extension { Object *replica; + Objset *removed_replicas; } multimaster_mtnode_extension; void *multimaster_mtnode_extension_constructor(void *object, void *parent); void multimaster_mtnode_extension_destructor(void *ext, void *object, void *parent); @@ -638,7 +639,7 @@ void prot_notify_update(Repl_Protocol *rp); void prot_notify_agmt_changed(Repl_Protocol *rp, char *agmt_name); void prot_notify_window_opened(Repl_Protocol *rp); void prot_notify_window_closed(Repl_Protocol *rp); -Object *prot_get_replica_object(Repl_Protocol *rp); +Replica *prot_get_replica(Repl_Protocol *rp); void prot_replicate_now(Repl_Protocol *rp); Repl_Protocol *agmt_get_protocol(Repl_Agmt *ra); @@ -696,15 +697,16 @@ void replica_set_flag(Replica *r, uint32_t flag, PRBool clear); void replica_replace_flags(Replica *r, uint32_t flags); void replica_dump(Replica *r); void replica_set_enabled(Replica *r, PRBool enable); -Object *replica_get_replica_from_dn(const Slapi_DN *dn); +Replica *replica_get_replica_from_dn(const Slapi_DN *dn); +Replica *replica_get_replica_from_root(const char *repl_root); int replica_update_ruv(Replica *replica, const CSN *csn, const char *replica_purl); -Object *replica_get_replica_for_op(Slapi_PBlock *pb); +Replica *replica_get_replica_for_op(Slapi_PBlock *pb); /* the functions below manipulate replica hash */ int replica_init_name_hash(void); void replica_destroy_name_hash(void); -int replica_add_by_name(const char *name, Object *replica); +int replica_add_by_name(const char *name, Replica *replica); int replica_delete_by_name(const char *name); -Object *replica_get_by_name(const char *name); +Replica *replica_get_by_name(const char *name); void replica_flush(Replica *r); void replica_set_csn_assigned(Replica *r); void replica_get_referrals(const Replica *r, char ***referrals); @@ -723,7 +725,7 @@ int replica_add_by_dn(const char *dn); int replica_delete_by_dn(const char *dn); int replica_is_being_configured(const char *dn); void consumer5_set_mapping_tree_state_for_replica(const Replica *r, RUV *supplierRuv); -Object *replica_get_for_backend(const char *be_name); +Replica *replica_get_for_backend(const char *be_name); void replica_set_purge_delay(Replica *r, uint32_t purge_delay); void replica_set_tombstone_reap_interval(Replica *r, long interval); void replica_update_ruv_consumer(Replica *r, RUV *supplier_ruv); @@ -771,7 +773,7 @@ PRBool replica_is_state_flag_set(Replica *r, int32_t flag); void replica_set_state_flag(Replica *r, uint32_t flag, PRBool clear); void replica_set_tombstone_reap_stop(Replica *r, PRBool val); void replica_enable_replication(Replica *r); -void replica_disable_replication(Replica *r, Object *r_obj); +void replica_disable_replication(Replica *r); int replica_start_agreement(Replica *r, Repl_Agmt *ra); int windows_replica_start_agreement(Replica *r, Repl_Agmt *ra); @@ -790,7 +792,6 @@ void multimaster_be_state_change(void *handle, char *be_name, int old_be_state, typedef struct _cleanruv_data { - Object *repl_obj; Replica *replica; ReplicaId rid; Slapi_Task *task; @@ -815,7 +816,7 @@ typedef struct _cleanruv_purge_data int replica_config_init(void); void replica_config_destroy(void); int get_replica_type(Replica *r); -int replica_execute_cleanruv_task_ext(Object *r, ReplicaId rid); +int replica_execute_cleanruv_task_ext(Replica *r, ReplicaId rid); void add_cleaned_rid(cleanruv_data *data); int is_cleaned_rid(ReplicaId rid); int32_t check_and_set_cleanruv_task_count(ReplicaId rid); diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c index 0ef39df..f2f16f5 100644 --- a/ldap/servers/plugins/replication/repl5_agmt.c +++ b/ldap/servers/plugins/replication/repl5_agmt.c @@ -371,16 +371,13 @@ agmt_new_from_entry(Slapi_Entry *e) /* DN of entry at root of replicated area */ tmpstr = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaRoot); if (NULL != tmpstr) { - Object *repl_obj; Replica *replica; ra->replarea = slapi_sdn_new_dn_passin(tmpstr); /* now that we set the repl area, when can bump our agmt count */ - if ((repl_obj = replica_get_replica_from_dn(ra->replarea))) { - if ((replica = (Replica *)object_get_data(repl_obj))) { - replica_incr_agmt_count(replica); - } + if ((replica = replica_get_replica_from_dn(ra->replarea))) { + replica_incr_agmt_count(replica); } } @@ -584,7 +581,6 @@ agmt_delete(void **rap) { Repl_Agmt *ra; Replica *replica = NULL; - Object *repl_obj = NULL; PR_ASSERT(NULL != rap); PR_ASSERT(NULL != *rap); @@ -629,11 +625,9 @@ agmt_delete(void **rap) * Get the replica for this agreement from the repl area * so we can decrement the agmt count */ - repl_obj = replica_get_replica_from_dn(ra->replarea); - if (repl_obj) { - replica = (Replica *)object_get_data(repl_obj); + replica = replica_get_replica_from_dn(ra->replarea); + if (replica) { replica_decr_agmt_count(replica); - object_release(repl_obj); } slapi_sdn_free(&ra->replarea); } @@ -764,14 +758,12 @@ agmt_start(Repl_Agmt *ra) */ if (found_ruv) { Replica *r; - Object *repl_obj; char **maxcsns = NULL; int i; maxcsns = slapi_entry_attr_get_charray(entries[0], type_agmtMaxCSN); - repl_obj = prot_get_replica_object(ra->protocol); - if (repl_obj && maxcsns) { - r = (Replica *)object_get_data(repl_obj); + if (maxcsns) { + r = prot_get_replica(ra->protocol); if (r) { /* * Loop over all the agmt maxcsns and find ours... @@ -2699,18 +2691,15 @@ get_agmt_status(Slapi_PBlock *pb __attribute__((unused)), if (NULL != ra) { PRBool reapActive = PR_FALSE; Slapi_DN *replarea_sdn = NULL; - Object *repl_obj = NULL; replarea_sdn = agmt_get_replarea(ra); if (!replarea_sdn) { goto bail; } - repl_obj = replica_get_replica_from_dn(replarea_sdn); + Replica *replica = replica_get_replica_from_dn(replarea_sdn); slapi_sdn_free(&replarea_sdn); - if (repl_obj) { - Replica *replica = (Replica *)object_get_data(repl_obj); + if (replica) { reapActive = replica_get_tombstone_reap_active(replica); - object_release(repl_obj); } slapi_entry_attr_set_int(e, "nsds5replicaReapActive", (int)reapActive); @@ -3198,7 +3187,6 @@ agmt_remove_maxcsn(Repl_Agmt *ra) Slapi_PBlock *modpb = NULL; Slapi_Entry **entries = NULL; Replica *r = NULL; - Object *repl_obj; const Slapi_DN *tombstone_sdn = NULL; char *attrs[2]; int rc; @@ -3214,9 +3202,8 @@ agmt_remove_maxcsn(Repl_Agmt *ra) goto done; } - repl_obj = prot_get_replica_object(ra->protocol); - if (repl_obj) { - r = (Replica *)object_get_data(repl_obj); + r = prot_get_replica(ra->protocol); + if (r) { tombstone_sdn = replica_get_root(r); } else { slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "agmt_remove_maxcsn: Failed to get repl object.\n"); @@ -3259,9 +3246,8 @@ agmt_remove_maxcsn(Repl_Agmt *ra) goto done; } maxcsns = slapi_entry_attr_get_charray(entries[0], type_agmtMaxCSN); - repl_obj = prot_get_replica_object(ra->protocol); - if (repl_obj && maxcsns) { - r = (Replica *)object_get_data(repl_obj); + if (maxcsns) { + r = prot_get_replica(ra->protocol); if (r) { /* * Loop over all the agmt maxcsns and find ours... diff --git a/ldap/servers/plugins/replication/repl5_agmtlist.c b/ldap/servers/plugins/replication/repl5_agmtlist.c index 1bed8ad..f0ef612 100644 --- a/ldap/servers/plugins/replication/repl5_agmtlist.c +++ b/ldap/servers/plugins/replication/repl5_agmtlist.c @@ -136,7 +136,6 @@ add_new_agreement(Slapi_Entry *e) Repl_Agmt *ra = agmt_new_from_entry(e); Slapi_DN *replarea_sdn = NULL; Replica *replica = NULL; - Object *repl_obj = NULL; Object *ro = NULL; /* tell search result handler callback this entry was not sent */ @@ -152,17 +151,11 @@ add_new_agreement(Slapi_Entry *e) if (!replarea_sdn) { return 1; } - repl_obj = replica_get_replica_from_dn(replarea_sdn); + replica = replica_get_replica_from_dn(replarea_sdn); slapi_sdn_free(&replarea_sdn); - if (repl_obj) { - replica = (Replica *)object_get_data(repl_obj); - } rc = replica_start_agreement(replica, ra); - if (repl_obj) - object_release(repl_obj); - return rc; } @@ -798,11 +791,11 @@ agmtlist_get_next_agreement_for_replica(Replica *r, Object *prev) replica_root = replica_get_root(r); - if (prev) + if (prev) { obj = objset_next_obj(agmt_set, prev); - else + } else { obj = objset_first_obj(agmt_set); - + } for (; obj; obj = objset_next_obj(agmt_set, obj)) { agmt = (Repl_Agmt *)object_get_data(obj); if (!agmt) { diff --git a/ldap/servers/plugins/replication/repl5_connection.c b/ldap/servers/plugins/replication/repl5_connection.c index fb7d871..7488f14 100644 --- a/ldap/servers/plugins/replication/repl5_connection.c +++ b/ldap/servers/plugins/replication/repl5_connection.c @@ -282,11 +282,15 @@ conn_delete(Repl_Connection *conn) */ conn->delete_after_linger = PR_TRUE; } + } else { + destroy_it = PR_TRUE; } if (destroy_it) { - conn_delete_internal(conn); + PR_Unlock(conn->lock); + conn_delete_internal_ext(conn); + } else { + PR_Unlock(conn->lock); } - PR_Unlock(conn->lock); } void diff --git a/ldap/servers/plugins/replication/repl5_inc_protocol.c b/ldap/servers/plugins/replication/repl5_inc_protocol.c index 9140c34..29b1fb0 100644 --- a/ldap/servers/plugins/replication/repl5_inc_protocol.c +++ b/ldap/servers/plugins/replication/repl5_inc_protocol.c @@ -297,7 +297,7 @@ repl5_inc_result_threadmain(void *param) * Something other than a timeout, so we exit the loop. * First check if we were told to abort the session */; - Replica *r = (Replica *)object_get_data(rd->prp->replica_object); + Replica *r = rd->prp->replica; if (replica_get_release_timeout(r) && slapi_control_present(returned_controls, REPL_ABORT_SESSION_OID, @@ -629,7 +629,6 @@ static void repl5_inc_run(Private_Repl_Protocol *prp) { repl5_inc_private *prp_priv = (repl5_inc_private *)prp->private; - Replica *replica = NULL; CSN *cons_schema_csn; RUV *ruv = NULL; PRUint32 num_changes_sent; @@ -793,7 +792,6 @@ repl5_inc_run(Private_Repl_Protocol *prp) /* ONREPL - at this state we unconditionally acquire the replica ignoring all events. Not sure if this is good */ - object_acquire(prp->replica_object); rc = acquire_replica(prp, REPL_NSDS50_INCREMENTAL_PROTOCOL_OID, &ruv); use_busy_backoff_timer = PR_FALSE; /* default */ if (rc == ACQUIRE_SUCCESS) { @@ -808,7 +806,6 @@ repl5_inc_run(Private_Repl_Protocol *prp) } else if (rc == ACQUIRE_FATAL_ERROR) { next_state = STATE_STOP_FATAL_ERROR; } - object_release(prp->replica_object); break; case STATE_BACKOFF_START: @@ -956,6 +953,10 @@ repl5_inc_run(Private_Repl_Protocol *prp) /* richm: We at least need to let monitors know that the protocol has been * shutdown - maybe they can figure out why */ agmt_set_last_update_status(prp->agmt, 0, 0, "Protocol stopped"); + if (NULL != ruv) { + ruv_destroy(&ruv); + ruv = NULL; + } agmt_update_done(prp->agmt, 0); break; } @@ -1023,11 +1024,7 @@ repl5_inc_run(Private_Repl_Protocol *prp) case EXAMINE_RUV_OK: /* update our csn generator state with the consumer's ruv data */ dev_debug("repl5_inc_run(STATE_SENDING_UPDATES) -> examine_update_vector OK"); - object_acquire(prp->replica_object); - replica = object_get_data(prp->replica_object); - rc = replica_update_csngen_state(replica, ruv); - object_release(prp->replica_object); - replica = NULL; + rc = replica_update_csngen_state(prp->replica, ruv); if (rc == CSN_LIMIT_EXCEEDED) /* too much skew */ { slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "repl5_inc_run - %s: Fatal error - too much time skew between replicas!\n", @@ -1673,7 +1670,7 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu } } else { ConnResult replay_crc; - Replica *replica = (Replica *)object_get_data(prp->replica_object); + Replica *replica = prp->replica; PRBool subentry_update_needed = PR_FALSE; PRUint64 release_timeout = replica_get_release_timeout(replica); char csn_str[CSN_STRSIZE]; @@ -1980,19 +1977,15 @@ static int repl5_inc_stop(Private_Repl_Protocol *prp) { PRIntervalTime start, maxwait, now; - Replica *replica = NULL; PRUint64 timeout; int return_value; if ((timeout = agmt_get_protocol_timeout(prp->agmt)) == 0) { timeout = DEFAULT_PROTOCOL_TIMEOUT; - if (prp->replica_object) { - object_acquire(prp->replica_object); - replica = object_get_data(prp->replica_object); - if ((timeout = replica_get_protocol_timeout(replica)) == 0) { + if (prp->replica) { + if ((timeout = replica_get_protocol_timeout(prp->replica)) == 0) { timeout = DEFAULT_PROTOCOL_TIMEOUT; } - object_release(prp->replica_object); } } @@ -2019,28 +2012,24 @@ repl5_inc_stop(Private_Repl_Protocol *prp) PR_IntervalToSeconds(now - start)); } if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) { - if (NULL == prp->replica_object) { + if (NULL == prp->replica) { slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, - "repl5_inc_stop - %s: Protocol replica_object is NULL\n", + "repl5_inc_stop - %s: Protocol replica is NULL\n", agmt_get_long_name(prp->agmt)); } else { - Replica *replica; - object_acquire(prp->replica_object); - replica = object_get_data(prp->replica_object); - if (NULL == replica) { + if (NULL == prp->replica) { slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "repl5_inc_stop - %s:replica is NULL\n", agmt_get_long_name(prp->agmt)); } else { - Object *ruv_obj = replica_get_ruv(replica); + Object *ruv_obj = replica_get_ruv(prp->replica); if (NULL == ruv_obj) { slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "repl5_inc_stop - %s: rruv_obj is NULL\n", agmt_get_long_name(prp->agmt)); } else { - RUV *ruv; - object_acquire(ruv_obj); - ruv = (RUV *)object_get_data(ruv_obj); + /* object was acquired in replica_get_ruv */ + RUV *ruv = (RUV *)object_get_data(ruv_obj); if (NULL == ruv) { slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "repl5_inc_stop - %s: ruv is NULL\n", @@ -2052,7 +2041,6 @@ repl5_inc_stop(Private_Repl_Protocol *prp) object_release(ruv_obj); } } - object_release(prp->replica_object); } } return return_value; @@ -2110,7 +2098,7 @@ Repl_5_Inc_Protocol_new(Repl_Protocol *rp) prp->notify_window_opened = repl5_inc_notify_window_opened; prp->notify_window_closed = repl5_inc_notify_window_closed; prp->update_now = repl5_inc_update_now; - prp->replica_object = prot_get_replica_object(rp); + prp->replica = prot_get_replica(rp); if ((prp->lock = PR_NewLock()) == NULL) { goto loser; } @@ -2177,12 +2165,9 @@ examine_update_vector(Private_Repl_Protocol *prp, RUV *remote_ruv) char *remote_gen = ruv_get_replica_generation(remote_ruv); Object *local_ruv_obj; RUV *local_ruv; - Replica *replica; - PR_ASSERT(NULL != prp->replica_object); - replica = object_get_data(prp->replica_object); - PR_ASSERT(NULL != replica); - local_ruv_obj = replica_get_ruv(replica); + PR_ASSERT(NULL != prp->replica); + local_ruv_obj = replica_get_ruv(prp->replica); if (NULL != local_ruv_obj) { local_ruv = (RUV *)object_get_data(local_ruv_obj); PR_ASSERT(local_ruv); @@ -2367,33 +2352,24 @@ op2string(int op) void repl5_set_backoff_min(Private_Repl_Protocol *prp, int min) { - Replica *replica; - - replica = (Replica *)object_get_data(prp->replica_object); - if (replica) { - replica_set_backoff_min(replica, min); + if (prp->replica) { + replica_set_backoff_min(prp->replica, min); } } void repl5_set_backoff_max(Private_Repl_Protocol *prp, int max) { - Replica *replica; - - replica = object_get_data(prp->replica_object); - if (replica) { - replica_set_backoff_max(replica, max); + if (prp->replica) { + replica_set_backoff_max(prp->replica, max); } } int repl5_get_backoff_min(Private_Repl_Protocol *prp) { - Replica *replica; - - replica = object_get_data(prp->replica_object); - if (replica) { - return (int)replica_get_backoff_min(replica); + if (prp->replica) { + return (int)replica_get_backoff_min(prp->replica); } return PROTOCOL_BACKOFF_MINIMUM; } @@ -2401,11 +2377,8 @@ repl5_get_backoff_min(Private_Repl_Protocol *prp) int repl5_get_backoff_max(Private_Repl_Protocol *prp) { - Replica *replica; - - replica = object_get_data(prp->replica_object); - if (replica) { - return (int)replica_get_backoff_max(replica); + if (prp->replica) { + return (int)replica_get_backoff_max(prp->replica); } return PROTOCOL_BACKOFF_MAXIMUM; } diff --git a/ldap/servers/plugins/replication/repl5_mtnode_ext.c b/ldap/servers/plugins/replication/repl5_mtnode_ext.c index 745bd51..08a5861 100644 --- a/ldap/servers/plugins/replication/repl5_mtnode_ext.c +++ b/ldap/servers/plugins/replication/repl5_mtnode_ext.c @@ -34,29 +34,9 @@ multimaster_mtnode_extension_init() } void -multimaster_mtnode_free_replica_object(const Slapi_DN *root) -{ - mapping_tree_node *mtnode; - multimaster_mtnode_extension *ext; - - /* In some cases, root can be an empty SDN */ - /* Othertimes, a bug is setting root to 0x8, and I can't see where... */ - if (root != NULL) { - mtnode = slapi_get_mapping_tree_node_by_dn(root); - if (mtnode != NULL) { - ext = (multimaster_mtnode_extension *)repl_con_get_ext(REPL_CON_EXT_MTNODE, mtnode); - if (ext != NULL && ext->replica != NULL) { - object_release(ext->replica); - } - } - } -} - -void multimaster_mtnode_extension_destroy() { /* First iterate over the list to free the replica infos */ - /* dl_cleanup (root_list, (FREEFN)multimaster_mtnode_free_replica_object); */ dl_cleanup(root_list, (FREEFN)slapi_sdn_free); dl_free(&root_list); } @@ -95,7 +75,7 @@ multimaster_mtnode_construct_replicas() } ext->replica = object_new(r, replica_destroy); - if (replica_add_by_name(replica_get_name(r), ext->replica) != 0) { + if (replica_add_by_name(replica_get_name(r), r) != 0) { if (ext->replica) { object_release(ext->replica); ext->replica = NULL; @@ -148,11 +128,12 @@ multimaster_mtnode_extension_destructor(void *ext, void *object __attribute__((u } } -Object * +Replica * replica_get_replica_from_dn(const Slapi_DN *dn) { mapping_tree_node *mtnode; multimaster_mtnode_extension *ext; + Replica *r = NULL; if (dn == NULL) return NULL; @@ -173,17 +154,30 @@ replica_get_replica_from_dn(const Slapi_DN *dn) return NULL; } - if (ext->replica) - object_acquire(ext->replica); + if (ext->replica) { + r = (Replica *)object_get_data(ext->replica); + } + + return r; +} + +Replica * +replica_get_replica_from_root(const char *repl_root) +{ + Replica *replica =NULL; + Slapi_DN *repl_sdn = slapi_sdn_new_dn_byval(repl_root); + + replica = replica_get_replica_from_dn(repl_sdn); + slapi_sdn_free(&repl_sdn); - return ext->replica; + return replica; } -Object * +Replica * replica_get_replica_for_op(Slapi_PBlock *pb) { Slapi_DN *sdn = NULL; - Object *repl_obj = NULL; + Replica *replica = NULL; if (pb) { /* get replica generation for this operation */ @@ -191,18 +185,17 @@ replica_get_replica_for_op(Slapi_PBlock *pb) if (NULL == sdn) { goto bail; } - repl_obj = replica_get_replica_from_dn(sdn); + replica = replica_get_replica_from_dn(sdn); } bail: - return repl_obj; + return replica; } -Object * +Replica * replica_get_for_backend(const char *be_name) { Slapi_Backend *be; const Slapi_DN *suffix; - Object *r_obj; be = slapi_be_select_by_instance_name(be_name); if (NULL == be) @@ -210,7 +203,6 @@ replica_get_for_backend(const char *be_name) suffix = slapi_be_getsuffix(be, 0); - r_obj = replica_get_replica_from_dn(suffix); + return replica_get_replica_from_dn(suffix); - return r_obj; } diff --git a/ldap/servers/plugins/replication/repl5_plugins.c b/ldap/servers/plugins/replication/repl5_plugins.c index e5ed6de..abb3e68 100644 --- a/ldap/servers/plugins/replication/repl5_plugins.c +++ b/ldap/servers/plugins/replication/repl5_plugins.c @@ -523,7 +523,6 @@ static void purge_entry_state_information(Slapi_PBlock *pb) { CSN *purge_csn = NULL; - Object *repl_obj; Replica *replica; /* we don't want to trim RUV tombstone because we will @@ -531,47 +530,43 @@ purge_entry_state_information(Slapi_PBlock *pb) if (ruv_tombstone_op(pb)) return; - repl_obj = replica_get_replica_for_op(pb); - if (NULL != repl_obj) { - replica = object_get_data(repl_obj); - if (NULL != replica) { - purge_csn = replica_get_purge_csn(replica); + replica = replica_get_replica_for_op(pb); + if (NULL != replica) { + purge_csn = replica_get_purge_csn(replica); + } + if (NULL != purge_csn) { + Slapi_Entry *e; + int optype; + + slapi_pblock_get(pb, SLAPI_OPERATION_TYPE, &optype); + switch (optype) { + case SLAPI_OPERATION_MODIFY: + slapi_pblock_get(pb, SLAPI_MODIFY_EXISTING_ENTRY, &e); + break; + case SLAPI_OPERATION_MODRDN: + /* XXXggood - the following always gives a NULL entry - why? */ + slapi_pblock_get(pb, SLAPI_MODRDN_EXISTING_ENTRY, &e); + break; + case SLAPI_OPERATION_DELETE: + slapi_pblock_get(pb, SLAPI_DELETE_EXISTING_ENTRY, &e); + break; + default: + e = NULL; /* Don't purge on ADD - not needed */ + break; } - if (NULL != purge_csn) { - Slapi_Entry *e; - int optype; - - slapi_pblock_get(pb, SLAPI_OPERATION_TYPE, &optype); - switch (optype) { - case SLAPI_OPERATION_MODIFY: - slapi_pblock_get(pb, SLAPI_MODIFY_EXISTING_ENTRY, &e); - break; - case SLAPI_OPERATION_MODRDN: - /* XXXggood - the following always gives a NULL entry - why? */ - slapi_pblock_get(pb, SLAPI_MODRDN_EXISTING_ENTRY, &e); - break; - case SLAPI_OPERATION_DELETE: - slapi_pblock_get(pb, SLAPI_DELETE_EXISTING_ENTRY, &e); - break; - default: - e = NULL; /* Don't purge on ADD - not needed */ - break; - } - if (NULL != e) { - entry_purge_state_information(e, purge_csn); - /* conntion is always null */ - if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) { - char csn_str[CSN_STRSIZE]; - slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, - "purge_entry_state_information - From entry %s up to " - "CSN %s\n", - slapi_entry_get_dn(e), - csn_as_string(purge_csn, PR_FALSE, csn_str)); - } + if (NULL != e) { + entry_purge_state_information(e, purge_csn); + /* conntion is always null */ + if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) { + char csn_str[CSN_STRSIZE]; + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, + "purge_entry_state_information - From entry %s up to " + "CSN %s\n", + slapi_entry_get_dn(e), + csn_as_string(purge_csn, PR_FALSE, csn_str)); } - csn_free(&purge_csn); } - object_release(repl_obj); + csn_free(&purge_csn); } } int @@ -873,42 +868,36 @@ copy_operation_parameters(Slapi_PBlock *pb) Slapi_Operation *op = NULL; struct slapi_operation_parameters *op_params; supplier_operation_extension *opext; - Object *repl_obj; Replica *replica; - repl_obj = replica_get_replica_for_op(pb); + replica = replica_get_replica_for_op(pb); /* we are only interested in the updates to replicas */ - if (repl_obj) { - /* we only save the original operation parameters for replicated operations - since client operations don't go through urp engine and pblock data can be logged */ - slapi_pblock_get(pb, SLAPI_OPERATION, &op); - if (NULL == op) { - slapi_log_err(SLAPI_LOG_REPL, REPLICATION_SUBSYSTEM, - "copy_operation_parameters - operation is null.\n"); - return; - } - replica = (Replica *)object_get_data(repl_obj); - if (NULL == replica) { - slapi_log_err(SLAPI_LOG_REPL, REPLICATION_SUBSYSTEM, - "copy_operation_parameters - replica is null.\n"); - return; - } - opext = (supplier_operation_extension *)repl_sup_get_ext(REPL_SUP_EXT_OP, op); - if (operation_is_flag_set(op, OP_FLAG_REPLICATED) && - !operation_is_flag_set(op, OP_FLAG_REPL_FIXUP)) { - slapi_pblock_get(pb, SLAPI_OPERATION_PARAMETERS, &op_params); - opext->operation_parameters = operation_parameters_dup(op_params); - } - - /* this condition is needed to avoid re-entering backend serial lock - when ruv state is updated */ - if (!operation_is_flag_set(op, OP_FLAG_REPL_FIXUP)) { - /* save replica generation in case it changes */ - opext->repl_gen = replica_get_generation(replica); - } + if (NULL == replica) { + slapi_log_err(SLAPI_LOG_REPL, REPLICATION_SUBSYSTEM, + "copy_operation_parameters - replica is null.\n"); + return; + } + /* we only save the original operation parameters for replicated operations + since client operations don't go through urp engine and pblock data can be logged */ + slapi_pblock_get(pb, SLAPI_OPERATION, &op); + if (NULL == op) { + slapi_log_err(SLAPI_LOG_REPL, REPLICATION_SUBSYSTEM, + "copy_operation_parameters - operation is null.\n"); + return; + } + opext = (supplier_operation_extension *)repl_sup_get_ext(REPL_SUP_EXT_OP, op); + if (operation_is_flag_set(op, OP_FLAG_REPLICATED) && + !operation_is_flag_set(op, OP_FLAG_REPL_FIXUP)) { + slapi_pblock_get(pb, SLAPI_OPERATION_PARAMETERS, &op_params); + opext->operation_parameters = operation_parameters_dup(op_params); + } - object_release(repl_obj); + /* this condition is needed to avoid re-entering backend serial lock + when ruv state is updated */ + if (!operation_is_flag_set(op, OP_FLAG_REPL_FIXUP)) { + /* save replica generation in case it changes */ + opext->repl_gen = replica_get_generation(replica); } } @@ -951,7 +940,6 @@ write_changelog_and_ruv(Slapi_PBlock *pb) CSNPL_CTX *prim_csn; int rc; slapi_operation_parameters *op_params = NULL; - Object *repl_obj = NULL; int return_value = SLAPI_PLUGIN_SUCCESS; Replica *r; Slapi_Backend *be; @@ -978,13 +966,10 @@ write_changelog_and_ruv(Slapi_PBlock *pb) return return_value; } /* we only log changes for operations applied to a replica */ - repl_obj = replica_get_replica_for_op(pb); - if (repl_obj == NULL) + r = replica_get_replica_for_op(pb); + if (r == NULL) return return_value; - r = (Replica *)object_get_data(repl_obj); - PR_ASSERT(r); - slapi_pblock_get(pb, SLAPI_RESULT_CODE, &rc); if (rc) { /* op failed - just return */ cancel_opcsn(pb); @@ -1153,9 +1138,6 @@ common_return: set_thread_primary_csn(NULL, NULL); } } - if (repl_obj) { - object_release(repl_obj); - } return return_value; } @@ -1264,10 +1246,7 @@ process_postop(Slapi_PBlock *pb) connext = consumer_connection_extension_acquire_exclusive_access(conn, connid, opid); if (connext && connext->replica_acquired) { int zero = 0; - Replica *r = (Replica *)object_get_data((Object *)connext->replica_acquired); - - replica_relinquish_exclusive_access(r, connid, opid); - object_release((Object *)connext->replica_acquired); + replica_relinquish_exclusive_access(connext->replica_acquired, connid, opid); connext->replica_acquired = NULL; connext->isreplicationsession = 0; slapi_pblock_set(pb, SLAPI_CONN_IS_REPLICATION_SESSION, &zero); @@ -1302,30 +1281,27 @@ process_postop(Slapi_PBlock *pb) static int cancel_opcsn(Slapi_PBlock *pb) { - Object *repl_obj; + Replica *replica = NULL; Slapi_Operation *op = NULL; if (NULL == pb) { return SLAPI_PLUGIN_SUCCESS; } - repl_obj = replica_get_replica_for_op(pb); + replica = replica_get_replica_for_op(pb); slapi_pblock_get(pb, SLAPI_OPERATION, &op); if (NULL == op) { return SLAPI_PLUGIN_SUCCESS; } - if (repl_obj) { - Replica *r; + if (replica) { Object *gen_obj; CSNGen *gen; CSN *opcsn; - r = (Replica *)object_get_data(repl_obj); - PR_ASSERT(r); opcsn = operation_get_csn(op); if (!operation_is_flag_set(op, OP_FLAG_REPLICATED)) { /* get csn generator for the replica */ - gen_obj = replica_get_csngen(r); + gen_obj = replica_get_csngen(replica); PR_ASSERT(gen_obj); gen = (CSNGen *)object_get_data(gen_obj); @@ -1337,13 +1313,11 @@ cancel_opcsn(Slapi_PBlock *pb) } else if (!operation_is_flag_set(op, OP_FLAG_REPL_FIXUP)) { Object *ruv_obj; - ruv_obj = replica_get_ruv(r); + ruv_obj = replica_get_ruv(replica); PR_ASSERT(ruv_obj); - ruv_cancel_csn_inprogress(r, (RUV *)object_get_data(ruv_obj), opcsn, replica_get_rid(r)); + ruv_cancel_csn_inprogress(replica, (RUV *)object_get_data(ruv_obj), opcsn, replica_get_rid(replica)); object_release(ruv_obj); } - - object_release(repl_obj); } return SLAPI_PLUGIN_SUCCESS; @@ -1373,14 +1347,13 @@ ruv_tombstone_op(Slapi_PBlock *pb) static PRBool process_operation(Slapi_PBlock *pb, const CSN *csn) { - Object *r_obj; Replica *r; Object *ruv_obj; RUV *ruv; int rc; - r_obj = replica_get_replica_for_op(pb); - if (r_obj == NULL) { + r = replica_get_replica_for_op(pb); + if (r == NULL) { char sessionid[REPL_SESSION_ID_SIZE]; get_repl_session_id(pb, sessionid, NULL); slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "process_operation - " @@ -1389,9 +1362,6 @@ process_operation(Slapi_PBlock *pb, const CSN *csn) return PR_FALSE; } - r = (Replica *)object_get_data(r_obj); - PR_ASSERT(r); - ruv_obj = replica_get_ruv(r); PR_ASSERT(ruv_obj); @@ -1401,7 +1371,6 @@ process_operation(Slapi_PBlock *pb, const CSN *csn) rc = ruv_add_csn_inprogress(r, ruv, csn); object_release(ruv_obj); - object_release(r_obj); return (rc == RUV_SUCCESS); } @@ -1409,13 +1378,12 @@ process_operation(Slapi_PBlock *pb, const CSN *csn) static PRBool is_mmr_replica(Slapi_PBlock *pb) { - Object *r_obj; + Replica *replica; - r_obj = replica_get_replica_for_op(pb); - if (r_obj == NULL) { + replica = replica_get_replica_for_op(pb); + if (replica == NULL) { return PR_FALSE; } - object_release(r_obj); return PR_TRUE; } @@ -1459,16 +1427,13 @@ replica_get_purl_for_op(const Replica *r __attribute__((unused)), Slapi_PBlock * void multimaster_be_state_change(void *handle __attribute__((unused)), char *be_name, int old_be_state, int new_be_state) { - Object *r_obj; Replica *r; /* check if we have replica associated with the backend */ - r_obj = replica_get_for_backend(be_name); - if (r_obj == NULL) + r = replica_get_for_backend(be_name); + if (r == NULL) { return; - - r = (Replica *)object_get_data(r_obj); - PR_ASSERT(r); + } if (new_be_state == SLAPI_BE_STATE_ON) { /* backend came back online - restart replication */ @@ -1481,16 +1446,15 @@ multimaster_be_state_change(void *handle __attribute__((unused)), char *be_name, slapi_log_err(SLAPI_LOG_NOTICE, repl_plugin_name, "multimaster_be_state_change - " "Replica %s is going offline; disabling replication\n", slapi_sdn_get_ndn(replica_get_root(r))); - replica_disable_replication(r, r_obj); + replica_disable_replication(r); } else if (new_be_state == SLAPI_BE_STATE_DELETE) { /* backend is about to be removed - disable replication */ if (old_be_state == SLAPI_BE_STATE_ON) { slapi_log_err(SLAPI_LOG_NOTICE, repl_plugin_name, "multimaster_be_state_change - " "Replica %s is about to be deleted; disabling replication\n", slapi_sdn_get_ndn(replica_get_root(r))); - replica_disable_replication(r, r_obj); + replica_disable_replication(r); } } - object_release(r_obj); } diff --git a/ldap/servers/plugins/replication/repl5_prot_private.h b/ldap/servers/plugins/replication/repl5_prot_private.h index f783859..5b2e1b3 100644 --- a/ldap/servers/plugins/replication/repl5_prot_private.h +++ b/ldap/servers/plugins/replication/repl5_prot_private.h @@ -40,7 +40,7 @@ typedef struct private_repl_protocol Repl_Connection *conn; int last_acquire_response_code; Repl_Agmt *agmt; - Object *replica_object; + Replica *replica; void *private; PRBool replica_acquired; int repl50consumer; /* Flag to tell us if this is a 5.0-style consumer we're talking to */ diff --git a/ldap/servers/plugins/replication/repl5_protocol.c b/ldap/servers/plugins/replication/repl5_protocol.c index bab3fe9..dfdb698 100644 --- a/ldap/servers/plugins/replication/repl5_protocol.c +++ b/ldap/servers/plugins/replication/repl5_protocol.c @@ -39,7 +39,7 @@ typedef struct repl_protocol Repl_Agmt *agmt; /* The replication agreement we're servicing */ Repl_Connection *conn; /* Connection to remote server */ void (*delete_conn)(Repl_Connection *conn); /* mmr conn is different than winsync conn */ - Object *replica_object; /* Local replica. If non-NULL, replica object is acquired */ + Replica *replica; /* Local replica */ int state; int next_state; PRThread *agmt_thread; @@ -77,8 +77,8 @@ prot_new(Repl_Agmt *agmt, int protocol_state) rp->conn = NULL; /* Acquire the local replica object */ replarea_sdn = agmt_get_replarea(agmt); - rp->replica_object = replica_get_replica_from_dn(replarea_sdn); - if (NULL == rp->replica_object) { + rp->replica = replica_get_replica_from_dn(replarea_sdn); + if (NULL == rp->replica) { /* Whoa, no local replica!?!? */ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "prot_new - %s: Unable to locate replica object for local replica %s\n", @@ -110,11 +110,11 @@ done: return rp; } -Object * -prot_get_replica_object(Repl_Protocol *rp) +Replica * +prot_get_replica(Repl_Protocol *rp) { PR_ASSERT(NULL != rp); - return rp->replica_object; + return rp->replica; } Repl_Agmt * @@ -143,9 +143,6 @@ prot_free(Repl_Protocol **rpp) if (NULL != rp->prp_total) { rp->prp_total->delete (&rp->prp_total); } - if (NULL != rp->replica_object) { - object_release(rp->replica_object); - } if ((NULL != rp->conn) && (NULL != rp->delete_conn)) { rp->delete_conn(rp->conn); rp->conn = NULL; @@ -257,15 +254,12 @@ prot_thread_main(void *arg) break; case STATE_PERFORMING_TOTAL_UPDATE: { Slapi_DN *dn = agmt_get_replarea(agmt); - Replica *replica = NULL; - Object *replica_obj = replica_get_replica_from_dn(dn); + Replica *replica = replica_get_replica_from_dn(dn); slapi_sdn_free(&dn); - if (replica_obj) { - replica = (Replica *)object_get_data(replica_obj); + if (replica) { /* If total update against this replica is in progress, * we should not initiate the total update to other replicas. */ if (replica_is_state_flag_set(replica, REPLICA_TOTAL_EXCL_RECV)) { - object_release(replica_obj); slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "prot_thread_main - %s: total update on the replica is in progress. " "Cannot initiate the total update.\n", @@ -291,9 +285,8 @@ prot_thread_main(void *arg) replica initialization is completed. */ agmt_replica_init_done(agmt); - if (replica_obj) { + if (replica) { replica_set_state_flag(replica, REPLICA_TOTAL_EXCL_SEND, 1); - object_release(replica_obj); } break; } diff --git a/ldap/servers/plugins/replication/repl5_protocol_util.c b/ldap/servers/plugins/replication/repl5_protocol_util.c index bb9f9e7..c3627d6 100644 --- a/ldap/servers/plugins/replication/repl5_protocol_util.c +++ b/ldap/servers/plugins/replication/repl5_protocol_util.c @@ -31,27 +31,23 @@ Code common to both incremental and total protocols. CSN * get_current_csn(Slapi_DN *replarea_sdn) { - Object *replica_obj; Replica *replica; Object *gen_obj; CSNGen *gen; CSN *current_csn = NULL; if (NULL != replarea_sdn) { - replica_obj = replica_get_replica_from_dn(replarea_sdn); - if (NULL != replica_obj) { - replica = object_get_data(replica_obj); - if (NULL != replica) { - gen_obj = replica_get_csngen(replica); - if (NULL != gen_obj) { - gen = (CSNGen *)object_get_data(gen_obj); - if (NULL != gen) { - if (csngen_new_csn(gen, ¤t_csn, - PR_FALSE /* notify */) != CSN_SUCCESS) { - csn_free(¤t_csn); - } - object_release(gen_obj); + replica = replica_get_replica_from_dn(replarea_sdn); + if (NULL != replica) { + gen_obj = replica_get_csngen(replica); + if (NULL != gen_obj) { + gen = (CSNGen *)object_get_data(gen_obj); + if (NULL != gen) { + if (csngen_new_csn(gen, ¤t_csn, + PR_FALSE /* notify */) != CSN_SUCCESS) { + csn_free(¤t_csn); } + object_release(gen_obj); } } } @@ -103,21 +99,16 @@ acquire_replica(Private_Repl_Protocol *prp, char *prot_oid, RUV **ruv) } if (strcmp(prot_oid, REPL_NSDS50_INCREMENTAL_PROTOCOL_OID) == 0) { - Replica *replica; Object *supl_ruv_obj, *cons_ruv_obj; PRBool is_newer = PR_FALSE; - object_acquire(prp->replica_object); - replica = object_get_data(prp->replica_object); - supl_ruv_obj = replica_get_ruv(replica); + supl_ruv_obj = replica_get_ruv(prp->replica); cons_ruv_obj = agmt_get_consumer_ruv(prp->agmt); is_newer = ruv_is_newer(supl_ruv_obj, cons_ruv_obj); if (supl_ruv_obj) object_release(supl_ruv_obj); if (cons_ruv_obj) object_release(cons_ruv_obj); - object_release(prp->replica_object); - replica = NULL; if (is_newer == PR_FALSE) { prp->last_acquire_response_code = NSDS50_REPL_UPTODATE; diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c index c150ff9..94507bf 100644 --- a/ldap/servers/plugins/replication/repl5_replica.c +++ b/ldap/servers/plugins/replication/repl5_replica.c @@ -1494,7 +1494,6 @@ replica_reload_ruv(Replica *r) Object *old_ruv_obj = NULL, *new_ruv_obj = NULL; RUV *upper_bound_ruv = NULL; RUV *new_ruv = NULL; - Object *r_obj; PR_ASSERT(r); @@ -1547,8 +1546,6 @@ replica_reload_ruv(Replica *r) if (!ruv_covers_ruv(new_ruv, upper_bound_ruv) || !ruv_covers_ruv(upper_bound_ruv, new_ruv)) { - /* create a temporary replica object to conform to the interface */ - r_obj = object_new(r, NULL); /* We can't use existing changelog - remove existing file */ slapi_log_err(SLAPI_LOG_WARNING, repl_plugin_name, "replica_reload_ruv - " @@ -1556,15 +1553,13 @@ replica_reload_ruv(Replica *r) " Recreating the changelog file. This could affect replication with replica's " " consumers in which case the consumers should be reinitialized.\n", slapi_sdn_get_dn(r->repl_root)); - rc = cl5DeleteDBSync(r_obj); + rc = cl5DeleteDBSync(r); /* reinstate new ruv */ replica_lock(r->repl_lock); r->repl_ruv = new_ruv_obj; - object_release(r_obj); - if (rc == CL5_SUCCESS) { /* log changes to mark starting point for replication */ rc = replica_log_ruv_elements_nolock(r); @@ -1622,7 +1617,7 @@ replica_check_for_data_reload(Replica *r, void *arg __attribute__((unused))) int rc = 0; RUV *upper_bound_ruv = NULL; RUV *r_ruv = NULL; - Object *r_obj, *ruv_obj; + Object *ruv_obj; PR_ASSERT(r); @@ -1681,8 +1676,6 @@ replica_check_for_data_reload(Replica *r, void *arg __attribute__((unused))) rc = ruv_compare_ruv(upper_bound_ruv, "changelog max RUV", r_ruv, "database RUV", 0, SLAPI_LOG_ERR); if (RUV_COMP_IS_FATAL(rc)) { - /* create a temporary replica object to conform to the interface */ - r_obj = object_new(r, NULL); /* We can't use existing changelog - remove existing file */ slapi_log_err(SLAPI_LOG_WARNING, repl_plugin_name, "replica_check_for_data_reload - " @@ -1692,9 +1685,7 @@ replica_check_for_data_reload(Replica *r, void *arg __attribute__((unused))) "consumers should be reinitialized.\n", slapi_sdn_get_dn(r->repl_root)); - rc = cl5DeleteDBSync(r_obj); - - object_release(r_obj); + rc = cl5DeleteDBSync(r); if (rc == CL5_SUCCESS) { /* log changes to mark starting point for replication */ @@ -2128,12 +2119,10 @@ replica_check_for_tasks(time_t when __attribute__((unused)), void *arg) const Slapi_DN *repl_root = (Slapi_DN *)arg; Slapi_Entry *e = NULL; Replica *r = NULL; - Object *repl_obj = NULL;; char **clean_vals; e = _replica_get_config_entry(repl_root, NULL); - repl_obj = replica_get_replica_from_dn(repl_root); - r = (Replica *)object_get_data(repl_obj); + r = replica_get_replica_from_dn(repl_root); if (e == NULL || r == NULL || ldif_dump_is_running() == PR_TRUE) { /* If db2ldif is being run, do not check if there are incomplete tasks */ @@ -2354,7 +2343,6 @@ replica_check_for_tasks(time_t when __attribute__((unused)), void *arg) } slapi_ch_array_free(clean_vals); } - object_release(repl_obj); slapi_entry_free(e); } @@ -2678,7 +2666,6 @@ replica_update_state(time_t when __attribute__((unused)), void *arg) { int rc; const char *replica_name = (const char *)arg; - Object *replica_object = NULL; Replica *r; Slapi_Mod smod; LDAPMod *mods[3]; @@ -2691,20 +2678,9 @@ replica_update_state(time_t when __attribute__((unused)), void *arg) if (NULL == replica_name) return; - /* - * replica_get_by_name() will acquire the replica object - * and that could prevent the replica from being destroyed - * until the object_release is called. - */ - replica_object = replica_get_by_name(replica_name); - if (NULL == replica_object) { - return; - } - - /* We have a reference, so replica won't vanish on us. */ - r = (Replica *)object_get_data(replica_object); + r = replica_get_by_name(replica_name); if (NULL == r) { - goto done; + return; } replica_lock(r->repl_lock); @@ -2713,7 +2689,7 @@ replica_update_state(time_t when __attribute__((unused)), void *arg) or no CSN was assigned - bail out */ if (r->state_update_inprogress) { replica_unlock(r->repl_lock); - goto done; + return; } /* This might be a consumer */ @@ -2725,7 +2701,7 @@ replica_update_state(time_t when __attribute__((unused)), void *arg) "replica_update_state - Failed write RUV for %s\n", slapi_sdn_get_dn(r->repl_root)); } - goto done; + return; } /* ONREPL update csn generator state of an updatable replica only */ @@ -2734,7 +2710,7 @@ replica_update_state(time_t when __attribute__((unused)), void *arg) rc = csngen_get_state((CSNGen *)object_get_data(r->repl_csngen), &smod); if (rc != 0) { replica_unlock(r->repl_lock); - goto done; + return; } r->state_update_inprogress = PR_TRUE; @@ -2746,7 +2722,7 @@ replica_update_state(time_t when __attribute__((unused)), void *arg) "replica_update_state - Failed to get the config dn for %s\n", slapi_sdn_get_dn(r->repl_root)); replica_unlock(r->repl_lock); - goto done; + return; } pb = slapi_pblock_new(); mods[0] = (LDAPMod *)slapi_mod_get_ldapmod_byref(&smod); @@ -2804,9 +2780,6 @@ replica_update_state(time_t when __attribute__((unused)), void *arg) slapi_pblock_destroy(pb); slapi_mod_done(&smod); -done: - if (replica_object) - object_release(replica_object); } int @@ -2885,7 +2858,6 @@ replica_write_ruv(Replica *r) int replica_ruv_smods_for_op(Slapi_PBlock *pb, char **uniqueid, Slapi_Mods **smods) { - Object *replica_obj; Object *ruv_obj; Replica *replica; RUV *ruv; @@ -2908,10 +2880,10 @@ replica_ruv_smods_for_op(Slapi_PBlock *pb, char **uniqueid, Slapi_Mods **smods) return (-1); } - replica_obj = replica_get_replica_for_op(pb); + replica = replica_get_replica_for_op(pb); slapi_pblock_get(pb, SLAPI_OPERATION, &op); - if (NULL != replica_obj && NULL != op) { + if (NULL != replica && NULL != op) { opcsn = operation_get_csn(op); } @@ -2920,9 +2892,6 @@ replica_ruv_smods_for_op(Slapi_PBlock *pb, char **uniqueid, Slapi_Mods **smods) return (0); } - replica = (Replica *)object_get_data(replica_obj); - PR_ASSERT(replica); - ruv_obj = replica_get_ruv(replica); PR_ASSERT(ruv_obj); @@ -2932,7 +2901,6 @@ replica_ruv_smods_for_op(Slapi_PBlock *pb, char **uniqueid, Slapi_Mods **smods) ruv_copy = ruv_dup(ruv); object_release(ruv_obj); - object_release(replica_obj); rc = ruv_set_max_csn_ext(ruv_copy, opcsn, NULL, PR_TRUE); if (rc == RUV_COVERS_CSN) { /* change would "revert" RUV - ignored */ @@ -3103,7 +3071,6 @@ _replica_reap_tombstones(void *arg) { const char *replica_name = (const char *)arg; Slapi_PBlock *pb = NULL; - Object *replica_object = NULL; Replica *replica = NULL; CSN *purge_csn = NULL; @@ -3117,23 +3084,10 @@ _replica_reap_tombstones(void *arg) goto done; } - /* - * replica_get_by_name() will acquire the replica object - * and that could prevent the replica from being destroyed - * until the object_release is called. - */ - replica_object = replica_get_by_name(replica_name); - if (NULL == replica_object) { - slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, - "_replica_reap_tombstones - Replica object %s is null in tombstone reap\n", replica_name); - goto done; - } - - /* We have a reference, so replica won't vanish on us. */ - replica = (Replica *)object_get_data(replica_object); + replica = replica_get_by_name(replica_name); if (NULL == replica) { slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, - "_replica_reap_tombstones - Replica %s is null in tombstone reap\n", replica_name); + "_replica_reap_tombstones - Replica object %s is null in tombstone reap\n", replica_name); goto done; } @@ -3242,11 +3196,6 @@ done: slapi_free_search_results_internal(pb); slapi_pblock_destroy(pb); } - if (NULL != replica_object) { - object_release(replica_object); - replica_object = NULL; - replica = NULL; - } slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "_replica_reap_tombstones - Finished tombstone reap for replica %s.\n", @@ -3264,46 +3213,33 @@ static void eq_cb_reap_tombstones(time_t when __attribute__((unused)), void *arg) { const char *replica_name = (const char *)arg; - Object *replica_object = NULL; Replica *replica = NULL; if (NULL != replica_name) { - /* - * replica_get_by_name() will acquire the replica object - * and that could prevent the replica from being destroyed - * until the object_release is called. - */ - replica_object = replica_get_by_name(replica_name); - if (NULL != replica_object) { - /* We have a reference, so replica won't vanish on us. */ - replica = (Replica *)object_get_data(replica_object); - if (replica) { - - replica_lock(replica->repl_lock); - - /* No action if purge is disabled or the previous purge is not done yet */ - if (replica->tombstone_reap_interval != 0 && - replica->tombstone_reap_active == PR_FALSE) { - /* set the flag here to minimize race conditions */ - replica->tombstone_reap_active = PR_TRUE; - if (PR_CreateThread(PR_USER_THREAD, - _replica_reap_tombstones, (void *)replica_name, - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, - SLAPD_DEFAULT_THREAD_STACKSIZE) == NULL) { - replica->tombstone_reap_active = PR_FALSE; - slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, - "eq_cb_reap_tombstones - Unable to create the tombstone reap thread for replica %s. " - "Possible system resources problem\n", - replica_name); - } + replica = replica_get_by_name(replica_name); + if (replica) { + replica_lock(replica->repl_lock); + + /* No action if purge is disabled or the previous purge is not done yet */ + if (replica->tombstone_reap_interval != 0 && + replica->tombstone_reap_active == PR_FALSE) { + /* set the flag here to minimize race conditions */ + replica->tombstone_reap_active = PR_TRUE; + if (PR_CreateThread(PR_USER_THREAD, + _replica_reap_tombstones, (void *)replica_name, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, + SLAPD_DEFAULT_THREAD_STACKSIZE) == NULL) { + replica->tombstone_reap_active = PR_FALSE; + slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, + "eq_cb_reap_tombstones - Unable to create the tombstone reap thread for replica %s. " + "Possible system resources problem\n", + replica_name); } - /* reap thread will wait until this lock is released */ - replica_unlock(replica->repl_lock); } - object_release(replica_object); - replica_object = NULL; - replica = NULL; + /* reap thread will wait until this lock is released */ + replica_unlock(replica->repl_lock); } + replica = NULL; } } @@ -3875,7 +3811,7 @@ replica_enable_replication(Replica *r) /* replica is about to be taken offline */ void -replica_disable_replication(Replica *r, Object *r_obj __attribute__((unused))) +replica_disable_replication(Replica *r) { char *current_purl = NULL; char *p_locking_purl = NULL; @@ -3999,47 +3935,42 @@ CSN * replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn) { CSN *opcsn = NULL; - Object *replica_obj; - - replica_obj = replica_get_replica_for_op(pb); - if (NULL != replica_obj) { - Replica *replica = (Replica *)object_get_data(replica_obj); - if (NULL != replica) { - Slapi_Operation *op; - slapi_pblock_get(pb, SLAPI_OPERATION, &op); - if (replica->repl_type != REPLICA_TYPE_READONLY) { - Object *gen_obj = replica_get_csngen(replica); - if (NULL != gen_obj) { - CSNGen *gen = (CSNGen *)object_get_data(gen_obj); - if (NULL != gen) { - /* The new CSN should be greater than the base CSN */ + + Replica *replica = replica_get_replica_for_op(pb); + if (NULL != replica) { + Slapi_Operation *op; + slapi_pblock_get(pb, SLAPI_OPERATION, &op); + if (replica->repl_type != REPLICA_TYPE_READONLY) { + Object *gen_obj = replica_get_csngen(replica); + if (NULL != gen_obj) { + CSNGen *gen = (CSNGen *)object_get_data(gen_obj); + if (NULL != gen) { + /* The new CSN should be greater than the base CSN */ + csngen_new_csn(gen, &opcsn, PR_FALSE /* don't notify */); + if (csn_compare(opcsn, basecsn) <= 0) { + char opcsnstr[CSN_STRSIZE], basecsnstr[CSN_STRSIZE]; + char opcsn2str[CSN_STRSIZE]; + + csn_as_string(opcsn, PR_FALSE, opcsnstr); + csn_as_string(basecsn, PR_FALSE, basecsnstr); + csn_free(&opcsn); + csngen_adjust_time(gen, basecsn); csngen_new_csn(gen, &opcsn, PR_FALSE /* don't notify */); - if (csn_compare(opcsn, basecsn) <= 0) { - char opcsnstr[CSN_STRSIZE], basecsnstr[CSN_STRSIZE]; - char opcsn2str[CSN_STRSIZE]; - - csn_as_string(opcsn, PR_FALSE, opcsnstr); - csn_as_string(basecsn, PR_FALSE, basecsnstr); - csn_free(&opcsn); - csngen_adjust_time(gen, basecsn); - csngen_new_csn(gen, &opcsn, PR_FALSE /* don't notify */); - csn_as_string(opcsn, PR_FALSE, opcsn2str); - slapi_log_err(SLAPI_LOG_WARNING, repl_plugin_name, - "replica_generate_next_csn - " - "opcsn=%s <= basecsn=%s, adjusted opcsn=%s\n", - opcsnstr, basecsnstr, opcsn2str); - } - /* - * Insert opcsn into the csn pending list. - * This is the notify effect in csngen_new_csn(). - */ - assign_csn_callback(opcsn, (void *)replica); + csn_as_string(opcsn, PR_FALSE, opcsn2str); + slapi_log_err(SLAPI_LOG_WARNING, repl_plugin_name, + "replica_generate_next_csn - " + "opcsn=%s <= basecsn=%s, adjusted opcsn=%s\n", + opcsnstr, basecsnstr, opcsn2str); } - object_release(gen_obj); + /* + * Insert opcsn into the csn pending list. + * This is the notify effect in csngen_new_csn(). + */ + assign_csn_callback(opcsn, (void *)replica); } + object_release(gen_obj); } } - object_release(replica_obj); } return opcsn; @@ -4054,20 +3985,15 @@ replica_get_attr(Slapi_PBlock *pb, const char *type, void *value) { int rc = -1; - Object *replica_obj; - replica_obj = replica_get_replica_for_op(pb); - if (NULL != replica_obj) { - Replica *replica = (Replica *)object_get_data(replica_obj); - if (NULL != replica) { - if (strcasecmp(type, type_replicaTombstonePurgeInterval) == 0) { - *((int *)value) = replica->tombstone_reap_interval; - rc = 0; - } else if (strcasecmp(type, type_replicaPurgeDelay) == 0) { - *((int *)value) = replica->repl_purge_delay; - rc = 0; - } + Replica *replica = replica_get_replica_for_op(pb); + if (NULL != replica) { + if (strcasecmp(type, type_replicaTombstonePurgeInterval) == 0) { + *((int *)value) = replica->tombstone_reap_interval; + rc = 0; + } else if (strcasecmp(type, type_replicaPurgeDelay) == 0) { + *((int *)value) = replica->repl_purge_delay; + rc = 0; } - object_release(replica_obj); } return rc; diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c index c761480..79b2575 100644 --- a/ldap/servers/plugins/replication/repl5_replica_config.c +++ b/ldap/servers/plugins/replication/repl5_replica_config.c @@ -54,11 +54,11 @@ static int replica_config_change_type_and_id(Replica *r, const char *new_type, c static int replica_config_change_updatedn(Replica *r, const LDAPMod *mod, char *returntext, int apply_mods); static int replica_config_change_updatedngroup(Replica *r, const LDAPMod *mod, char *returntext, int apply_mods); static int replica_config_change_flags(Replica *r, const char *new_flags, char *returntext, int apply_mods); -static int replica_execute_task(Object *r, const char *task_name, char *returntext, int apply_mods); -static int replica_execute_cl2ldif_task(Object *r, char *returntext); -static int replica_execute_ldif2cl_task(Object *r, char *returntext); -static int replica_execute_cleanruv_task(Object *r, ReplicaId rid, char *returntext); -static int replica_execute_cleanall_ruv_task(Object *r, ReplicaId rid, Slapi_Task *task, const char *force_cleaning, PRBool original_task, char *returntext); +static int replica_execute_task(Replica *r, const char *task_name, char *returntext, int apply_mods); +static int replica_execute_cl2ldif_task(Replica *r, char *returntext); +static int replica_execute_ldif2cl_task(Replica *r, char *returntext); +static int replica_execute_cleanruv_task(Replica *r, ReplicaId rid, char *returntext); +static int replica_execute_cleanall_ruv_task(Replica *r, ReplicaId rid, Slapi_Task *task, const char *force_cleaning, PRBool original_task, char *returntext); static void replica_cleanallruv_thread(void *arg); static void replica_send_cleanruv_task(Repl_Agmt *agmt, cleanruv_data *clean_data); static int check_agmts_are_alive(Replica *replica, ReplicaId rid, Slapi_Task *task); @@ -284,7 +284,7 @@ replica_config_add(Slapi_PBlock *pb __attribute__((unused)), mtnode_ext->replica = object_new(r, replica_destroy); /* Refcnt is 1 */ /* add replica object to the hash */ - *returncode = replica_add_by_name(replica_get_name(r), mtnode_ext->replica); /* Increments object refcnt */ + *returncode = replica_add_by_name(replica_get_name(r), r); /* Increments object refcnt */ /* delete the dn from the dn hash - done with configuration */ replica_delete_by_dn(replica_root); @@ -342,9 +342,6 @@ replica_config_modify(Slapi_PBlock *pb, mtnode_ext = _replica_config_get_mtnode_ext(e); PR_ASSERT(mtnode_ext); - if (mtnode_ext->replica) - object_acquire(mtnode_ext->replica); - if (mtnode_ext->replica == NULL) { PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, "Replica does not exist for %s", replica_root); slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_modify - %s\n", @@ -478,7 +475,7 @@ replica_config_modify(Slapi_PBlock *pb, break; } } else if (strcasecmp(config_attr, TASK_ATTR) == 0) { - *returncode = replica_execute_task(mtnode_ext->replica, config_attr_value, errortext, apply_mods); + *returncode = replica_execute_task(r, config_attr_value, errortext, apply_mods); } else if (strcasecmp(config_attr, attr_replicaReferral) == 0) { if (apply_mods) { Slapi_Mod smod; @@ -613,9 +610,6 @@ replica_config_modify(Slapi_PBlock *pb, } done: - if (mtnode_ext->replica) { - object_release(mtnode_ext->replica); - } PR_Unlock(s_configLock); @@ -668,9 +662,6 @@ replica_config_post_modify(Slapi_PBlock *pb, mtnode_ext = _replica_config_get_mtnode_ext(e); PR_ASSERT(mtnode_ext); - if (mtnode_ext->replica) - object_acquire(mtnode_ext->replica); - if (mtnode_ext->replica == NULL) { PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, "Replica does not exist for %s", replica_root); @@ -740,9 +731,6 @@ done: errortext, apply_mods); } - if (mtnode_ext->replica) - object_release(mtnode_ext->replica); - if (*returncode != LDAP_SUCCESS) { return SLAPI_DSE_CALLBACK_ERROR; } else { @@ -775,9 +763,8 @@ replica_config_delete(Slapi_PBlock *pb __attribute__((unused)), "The changelog for replica %s is no longer valid since " "the replica config is being deleted. Removing the changelog.\n", slapi_sdn_get_dn(replica_get_root(r))); - cl5DeleteDBSync(mtnode_ext->replica); + cl5DeleteDBSync(r); replica_delete_by_name(replica_get_name(r)); - object_release(mtnode_ext->replica); mtnode_ext->replica = NULL; } @@ -872,12 +859,10 @@ replica_config_search(Slapi_PBlock *pb, PR_ASSERT(mtnode_ext); if (mtnode_ext->replica) { - Replica *replica; - object_acquire(mtnode_ext->replica); + Replica *replica = (Replica *)object_get_data(mtnode_ext->replica); if (cl5GetState() == CL5_STATE_OPEN) { - changeCount = cl5GetOperationCount(mtnode_ext->replica); + changeCount = cl5GetOperationCount(replica); } - replica = (Replica *)object_get_data(mtnode_ext->replica); if (replica) { reapActive = replica_get_tombstone_reap_active(replica); } @@ -889,7 +874,6 @@ replica_config_search(Slapi_PBlock *pb, if (search_requested_attr(pb, type_ruvElementUpdatetime)) { replica_config_search_last_modified(pb, e, replica); } - object_release(mtnode_ext->replica); } sprintf(val, "%d", changeCount); slapi_entry_add_string(e, type_replicaChangeCount, val); @@ -1042,7 +1026,7 @@ replica_config_change_flags(Replica *r, const char *new_flags, char *returntext } static int -replica_execute_task(Object *r, const char *task_name, char *returntext, int apply_mods) +replica_execute_task(Replica *r, const char *task_name, char *returntext, int apply_mods) { if (strcasecmp(task_name, CL2LDIF_TASK) == 0) { @@ -1151,11 +1135,10 @@ replica_task_done(Replica *replica) } static int -replica_execute_cl2ldif_task(Object *r, char *returntext) +replica_execute_cl2ldif_task(Replica *replica, char *returntext) { int rc; - Object *rlist[2]; - Replica *replica; + Replica *rlist[2]; char fName[MAXPATHLEN]; char *clDir = NULL; @@ -1167,9 +1150,6 @@ replica_execute_cl2ldif_task(Object *r, char *returntext) goto bail; } - rlist[0] = r; - rlist[1] = NULL; - /* file is stored in the changelog directory and is named .ldif */ clDir = cl5GetDir(); @@ -1178,11 +1158,13 @@ replica_execute_cl2ldif_task(Object *r, char *returntext) goto bail; } - replica = (Replica *)object_get_data(r); if (NULL == replica) { rc = LDAP_OPERATIONS_ERROR; goto bail; } + rlist[0] = replica; + rlist[1] = NULL; + PR_snprintf(fName, MAXPATHLEN, "%s/%s.ldif", clDir, replica_get_name(replica)); slapi_log_err(SLAPI_LOG_INFO, repl_plugin_name, @@ -1210,11 +1192,10 @@ bail: } static int -replica_execute_ldif2cl_task(Object *r, char *returntext) +replica_execute_ldif2cl_task(Replica *replica, char *returntext) { int rc, imprc = 0; - Object *rlist[2]; - Replica *replica; + Replica *rlist[2]; char fName[MAXPATHLEN]; char *clDir = NULL; changelog5Config config; @@ -1227,9 +1208,6 @@ replica_execute_ldif2cl_task(Object *r, char *returntext) goto bail; } - rlist[0] = r; - rlist[1] = NULL; - /* file is stored in the changelog directory and is named .ldif */ clDir = cl5GetDir(); @@ -1238,11 +1216,12 @@ replica_execute_ldif2cl_task(Object *r, char *returntext) goto bail; } - replica = (Replica *)object_get_data(r); if (NULL == replica) { rc = LDAP_OPERATIONS_ERROR; goto bail; } + rlist[0] = replica; + rlist[1] = NULL; PR_snprintf(fName, MAXPATHLEN, "%s/%s.ldif", clDir, replica_get_name(replica)); @@ -1331,17 +1310,16 @@ _replica_config_get_mtnode_ext(const Slapi_Entry *e) } int -replica_execute_cleanruv_task_ext(Object *r, ReplicaId rid) +replica_execute_cleanruv_task_ext(Replica *r, ReplicaId rid) { return replica_execute_cleanruv_task(r, rid, NULL); } static int -replica_execute_cleanruv_task(Object *r, ReplicaId rid, char *returntext __attribute__((unused))) +replica_execute_cleanruv_task(Replica *replica, ReplicaId rid, char *returntext __attribute__((unused))) { Object *RUVObj; RUV *local_ruv = NULL; - Replica *replica = (Replica *)object_get_data(r); cleanruv_purge_data *purge_data; int rc = 0; PR_ASSERT(replica); @@ -1401,8 +1379,8 @@ replica_cleanall_ruv_task(Slapi_PBlock *pb __attribute__((unused)), Slapi_Task *task = NULL; const Slapi_DN *task_dn; Slapi_DN *dn = NULL; + Replica *replica; ReplicaId rid = -1; - Object *r; const char *force_cleaning; const char *base_dn; const char *rid_str; @@ -1481,7 +1459,7 @@ replica_cleanall_ruv_task(Slapi_PBlock *pb __attribute__((unused)), * Get the replica object */ dn = slapi_sdn_new_dn_byval(base_dn); - if ((r = replica_get_replica_from_dn(dn)) == NULL) { + if ((replica = replica_get_replica_from_dn(dn)) == NULL) { PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Could not find replica from dn(%s)", slapi_sdn_get_dn(dn)); cleanruv_log(task, rid, CLEANALLRUV_ID, SLAPI_LOG_ERR, "%s", returntext); *returncode = LDAP_OPERATIONS_ERROR; @@ -1490,7 +1468,7 @@ replica_cleanall_ruv_task(Slapi_PBlock *pb __attribute__((unused)), } /* clean the RUV's */ - rc = replica_execute_cleanall_ruv_task(r, rid, task, force_cleaning, original_task, returntext); + rc = replica_execute_cleanall_ruv_task(replica, rid, task, force_cleaning, original_task, returntext); out: if (rc) { @@ -1513,14 +1491,13 @@ out: * */ static int -replica_execute_cleanall_ruv_task(Object *r, ReplicaId rid, Slapi_Task *task, const char *force_cleaning, PRBool original_task, char *returntext __attribute__((unused))) +replica_execute_cleanall_ruv_task(Replica *replica, ReplicaId rid, Slapi_Task *task, const char *force_cleaning, PRBool original_task, char *returntext __attribute__((unused))) { struct berval *payload = NULL; Slapi_Task *pre_task = NULL; /* this is supposed to be null for logging */ cleanruv_data *data = NULL; PRThread *thread = NULL; CSN *maxcsn = NULL; - Replica *replica; char csnstr[CSN_STRSIZE]; char *ridstr = NULL; char *basedn = NULL; @@ -1531,9 +1508,7 @@ replica_execute_cleanall_ruv_task(Object *r, ReplicaId rid, Slapi_Task *task, co /* * Grab the replica */ - if (r) { - replica = (Replica *)object_get_data(r); - } else { + if (replica == NULL) { cleanruv_log(pre_task, rid, CLEANALLRUV_ID, SLAPI_LOG_ERR, "Replica object is NULL, aborting task"); return -1; } @@ -1598,7 +1573,6 @@ replica_execute_cleanall_ruv_task(Object *r, ReplicaId rid, Slapi_Task *task, co PR_Unlock(task_count_lock); goto fail; } - data->repl_obj = r; data->replica = replica; data->rid = rid; data->task = task; @@ -1634,8 +1608,6 @@ fail: ber_bvfree(payload); } csn_free(&maxcsn); - if (task) /* only the task acquires the r obj */ - object_release(r); done: @@ -1674,7 +1646,6 @@ replica_cleanallruv_thread(void *arg) int agmt_not_notified = 1; int found_dirty_rid = 1; int interval = 10; - int free_obj = 0; int aborted = 0; int rc = 0; @@ -1694,7 +1665,7 @@ replica_cleanallruv_thread(void *arg) /* * Initialize our settings */ - if (data->replica == NULL && data->repl_obj == NULL) { + if (data->replica == NULL) { /* * This thread was initiated at startup because the process did not finish. Due * to startup timing issues, we need to wait before grabbing the replica obj, as @@ -1703,22 +1674,15 @@ replica_cleanallruv_thread(void *arg) PR_Lock(notify_lock); PR_WaitCondVar(notify_cvar, PR_SecondsToInterval(10)); PR_Unlock(notify_lock); - data->repl_obj = replica_get_replica_from_dn(data->sdn); - if (data->repl_obj == NULL) { + data->replica = replica_get_replica_from_dn(data->sdn); + if (data->replica == NULL) { cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_ERR, "Unable to retrieve repl object from dn(%s).", data->sdn); aborted = 1; goto done; } - data->replica = (Replica *)object_get_data(data->repl_obj); - free_obj = 1; - } else if (data->replica == NULL && data->repl_obj) { - data->replica = (Replica *)object_get_data(data->repl_obj); - } else if (data->repl_obj == NULL && data->replica) { - data->repl_obj = object_new(data->replica, NULL); - free_obj = 1; } /* verify we have set our repl objects */ - if (data->repl_obj == NULL || data->replica == NULL) { + if (data->replica == NULL) { cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_ERR, "Unable to set the replica objects."); aborted = 1; goto done; @@ -1812,6 +1776,7 @@ replica_cleanallruv_thread(void *arg) agmt_not_notified = 1; cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, LOG_WARNING, "Failed to send task to replica (%s)", agmt_get_long_name(agmt)); if (strcasecmp(data->force, "no") == 0) { + object_release(agmt_obj); break; } } @@ -1846,7 +1811,7 @@ replica_cleanallruv_thread(void *arg) * Run the CLEANRUV task */ cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_INFO, "Cleaning local ruv's..."); - replica_execute_cleanruv_task(data->repl_obj, data->rid, returntext); + replica_execute_cleanruv_task(data->replica, data->rid, returntext); /* * Wait for all the replicas to be cleaned */ @@ -1872,6 +1837,7 @@ replica_cleanallruv_thread(void *arg) found_dirty_rid = 1; cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE, "Replica is not cleaned yet (%s)", agmt_get_long_name(agmt)); + object_release(agmt_obj); break; } agmt_obj = agmtlist_get_next_agreement_for_replica(data->replica, agmt_obj); @@ -1953,9 +1919,6 @@ done: if (data->payload) { ber_bvfree(data->payload); } - if (data->repl_obj && free_obj) { - object_release(data->repl_obj); - } csn_free(&data->maxcsn); slapi_sdn_free(&data->sdn); @@ -2100,6 +2063,7 @@ check_replicas_are_done_cleaning(cleanruv_data *data) not_all_cleaned = 0; } else { not_all_cleaned = 1; + object_release(agmt_obj); break; } agmt_obj = agmtlist_get_next_agreement_for_replica(data->replica, agmt_obj); @@ -2212,6 +2176,7 @@ check_replicas_are_done_aborting(cleanruv_data *data) not_all_aborted = 0; } else { not_all_aborted = 1; + object_release(agmt_obj); break; } agmt_obj = agmtlist_get_next_agreement_for_replica(data->replica, agmt_obj); @@ -2268,6 +2233,7 @@ check_agmts_are_caught_up(cleanruv_data *data, char *maxcsn) not_all_caughtup = 1; cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE, "Replica not caught up (%s)", agmt_get_long_name(agmt)); + object_release(agmt_obj); break; } agmt_obj = agmtlist_get_next_agreement_for_replica(data->replica, agmt_obj); @@ -2328,6 +2294,7 @@ check_agmts_are_alive(Replica *replica, ReplicaId rid, Slapi_Task *task) not_all_alive = 1; cleanruv_log(task, rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE, "Replica not online (%s)", agmt_get_long_name(agmt)); + object_release(agmt_obj); break; } agmt_obj = agmtlist_get_next_agreement_for_replica(replica, agmt_obj); @@ -2875,7 +2842,6 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb __attribute__((unused)), Slapi_DN *sdn = NULL; Replica *replica; ReplicaId rid = -1; - Object *r; PRBool original_task = PR_TRUE; const char *certify_all; const char *orig_val; @@ -2940,7 +2906,7 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb __attribute__((unused)), * Get the replica object */ sdn = slapi_sdn_new_dn_byval(base_dn); - if ((r = replica_get_replica_from_dn(sdn)) == NULL) { + if ((replica = replica_get_replica_from_dn(sdn)) == NULL) { PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Failed to find replica from dn(%s)", base_dn); cleanruv_log(task, rid, ABORT_CLEANALLRUV_ID, SLAPI_LOG_ERR, "%s", returntext); *returncode = LDAP_OPERATIONS_ERROR; @@ -2993,7 +2959,6 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb __attribute__((unused)), /* * Stop the cleaning, and delete the rid */ - replica = (Replica *)object_get_data(r); add_aborted_rid(rid, replica, (char *)base_dn, (char *)certify_all, original_task); stop_ruv_cleaning(); @@ -3012,7 +2977,6 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb __attribute__((unused)), original_task = PR_FALSE; } } - data->repl_obj = r; /* released in replica_abort_task_thread() */ data->replica = replica; data->task = task; data->payload = payload; @@ -3026,7 +2990,6 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb __attribute__((unused)), (void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE); if (thread == NULL) { - object_release(r); cleanruv_log(task, rid, ABORT_CLEANALLRUV_ID, SLAPI_LOG_ERR, "Unable to create abort thread. Aborting task."); *returncode = LDAP_OPERATIONS_ERROR; slapi_ch_free_string(&data->certify); @@ -3056,7 +3019,6 @@ replica_abort_task_thread(void *arg) Object *agmt_obj; int agmt_not_notified = 1; int interval = 10; - int release_it = 0; int count = 0, rc = 0; if (!data || slapi_is_shutting_down()) { @@ -3075,20 +3037,16 @@ replica_abort_task_thread(void *arg) /* * Need to build the replica from the dn */ - if (data->replica == NULL && data->repl_obj == NULL) { + if (data->replica == NULL) { /* * This thread was initiated at startup because the process did not finish. Due * to timing issues, we need to wait to grab the replica obj until we get here. */ - if ((data->repl_obj = replica_get_replica_from_dn(data->sdn)) == NULL) { + if ((data->replica = replica_get_replica_from_dn(data->sdn)) == NULL) { cleanruv_log(data->task, data->rid, ABORT_CLEANALLRUV_ID, SLAPI_LOG_ERR, "Failed to get replica object from dn (%s).", slapi_sdn_get_dn(data->sdn)); goto done; } - if (data->replica == NULL && data->repl_obj) { - data->replica = (Replica *)object_get_data(data->repl_obj); - release_it = 1; - } } /* @@ -3111,6 +3069,7 @@ replica_abort_task_thread(void *arg) if (strcasecmp(data->certify, "yes") == 0) { /* we are verifying all the replicas receive the abort task */ agmt_not_notified = 1; + object_release(agmt_obj); break; } else { /* we do not care if we could not reach a replica, just continue as if we did */ @@ -3183,8 +3142,6 @@ done: slapi_task_dec_refcount(data->task); slapi_log_err(SLAPI_LOG_PLUGIN, repl_plugin_name, "replica_abort_task_thread <-- refcount incremented.\n"); } - if (data->repl_obj && release_it) - object_release(data->repl_obj); if (data->payload) { ber_bvfree(data->payload); } diff --git a/ldap/servers/plugins/replication/repl5_replica_hash.c b/ldap/servers/plugins/replication/repl5_replica_hash.c index 175f15c..bb7b054 100644 --- a/ldap/servers/plugins/replication/repl5_replica_hash.c +++ b/ldap/servers/plugins/replication/repl5_replica_hash.c @@ -72,7 +72,7 @@ replica_destroy_name_hash() } int -replica_add_by_name(const char *name, Object *replica) +replica_add_by_name(const char *name, Replica *replica) { if (name == NULL || replica == NULL) { slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_add_by_name: NULL argument\n"); @@ -96,15 +96,11 @@ replica_add_by_name(const char *name, Object *replica) return -1; } - /* acquire replica object */ - object_acquire(replica); - /* add replica */ if (PL_HashTableAdd(s_hash, name, replica) == NULL) { slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_add_by_name: " "failed to add replica with name (%s); NSPR error - %d\n", name, PR_GetError()); - object_release(replica); slapi_rwlock_unlock(s_lock); return -1; } @@ -116,7 +112,7 @@ replica_add_by_name(const char *name, Object *replica) int replica_delete_by_name(const char *name) { - Object *replica; + Replica *replica; if (name == NULL) { slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_delete_by_name: " @@ -133,7 +129,7 @@ replica_delete_by_name(const char *name) slapi_rwlock_wrlock(s_lock); /* locate object */ - replica = (Object *)PL_HashTableLookup(s_hash, name); + replica = (Replica *)PL_HashTableLookup(s_hash, name); if (replica == NULL) { slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_delete_by_name: " "replica with name (%s) is not in the hash.\n", @@ -145,18 +141,15 @@ replica_delete_by_name(const char *name) /* remove from hash */ PL_HashTableRemove(s_hash, name); - /* release replica */ - object_release(replica); - slapi_rwlock_unlock(s_lock); return 0; } -Object * +Replica * replica_get_by_name(const char *name) { - Object *replica; + Replica *replica; if (name == NULL) { slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_get_by_name: " @@ -173,14 +166,12 @@ replica_get_by_name(const char *name) slapi_rwlock_rdlock(s_lock); /* locate object */ - replica = (Object *)PL_HashTableLookup(s_hash, name); + replica = (Replica *)PL_HashTableLookup(s_hash, name); if (replica == NULL) { slapi_rwlock_unlock(s_lock); return NULL; } - object_acquire(replica); - slapi_rwlock_unlock(s_lock); return replica; @@ -207,43 +198,29 @@ replica_enumerate_replicas(FNEnumReplica fn, void *arg) static PRIntn replica_destroy_hash_entry(PLHashEntry *he, PRIntn index __attribute__((unused)), void *arg __attribute__((unused))) { - Object *r_obj; Replica *r; if (he == NULL) { return HT_ENUMERATE_NEXT; } - r_obj = (Object *)he->value; - r = (Replica *)object_get_data(r_obj); - PR_ASSERT(r); + r = (Replica *)he->value; /* flash replica state to the disk */ replica_flush(r); - /* release replica object */ - object_release(r_obj); - return HT_ENUMERATE_REMOVE; } static PRIntn replica_enumerate(PLHashEntry *he, PRIntn index __attribute__((unused)), void *hash_data) { - Object *r_obj; Replica *r; struct repl_enum_data *data = hash_data; - r_obj = (Object *)he->value; - PR_ASSERT(r_obj); - - object_acquire(r_obj); - r = (Replica *)object_get_data(r_obj); - PR_ASSERT(r); + r = (Replica *)he->value; data->fn(r, data->arg); - object_release(r_obj); - return HT_ENUMERATE_NEXT; } diff --git a/ldap/servers/plugins/replication/repl5_tot_protocol.c b/ldap/servers/plugins/replication/repl5_tot_protocol.c index 977545c..3b65d6b 100644 --- a/ldap/servers/plugins/replication/repl5_tot_protocol.c +++ b/ldap/servers/plugins/replication/repl5_tot_protocol.c @@ -351,9 +351,7 @@ repl5_tot_run(Private_Repl_Protocol *prp) Slapi_DN *area_sdn = NULL; CSN *remote_schema_csn = NULL; int init_retry = 0; - Replica *replica; ReplicaId rid = 0; /* Used to create the replica keep alive subentry */ - Slapi_Entry *suffix = NULL; char **instances = NULL; Slapi_Backend *be = NULL; int is_entryrdn = 0; @@ -443,7 +441,6 @@ retry: pb = slapi_pblock_new(); - replica = (Replica *)object_get_data(prp->replica_object); /* * Get the info about the entryrdn vs. entrydn from the backend. * If NOT is_entryrdn, its ancestor entries are always found prior to an entry. @@ -456,6 +453,8 @@ retry: goto done; } be = slapi_be_select_by_instance_name(instances[0]); + slapi_ch_array_free(instances); + if (!be) { slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "repl5_tot_run - Unable to " "get the instance for the suffix \"%s\".\n", @@ -469,6 +468,7 @@ retry: * Entires are retireved sorted by parentid without the allid threshold. */ /* Get suffix */ + Slapi_Entry *suffix = NULL; rc = slapi_search_internal_get_entry(area_sdn, NULL, &suffix, repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION)); if (rc) { slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "repl5_tot_run - Unable to " @@ -506,8 +506,8 @@ retry: ctrls[1] = create_backend_control(area_sdn); /* Time to make sure it exists a keep alive subentry for that replica */ - if (replica) { - rid = replica_get_rid(replica); + if (prp->replica) { + rid = replica_get_rid(prp->replica); } replica_subentry_check(area_sdn, rid); @@ -517,6 +517,7 @@ retry: LDAP_SCOPE_SUBTREE, "(parentid>=1)", NULL, 0, ctrls, NULL, repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), OP_FLAG_BULK_IMPORT); cb_data.num_entries = 0UL; + slapi_entry_free(suffix); } else { /* Original total update */ /* we need to provide managedsait control so that referral entries can @@ -526,9 +527,8 @@ retry: ctrls[1] = create_backend_control(area_sdn); /* Time to make sure it exists a keep alive subentry for that replica */ - replica = (Replica *)object_get_data(prp->replica_object); - if (replica) { - rid = replica_get_rid(replica); + if (prp->replica) { + rid = replica_get_rid(prp->replica); } replica_subentry_check(area_sdn, rid); @@ -644,13 +644,11 @@ repl5_tot_stop(Private_Repl_Protocol *prp) int return_value; PRIntervalTime start, maxwait, now; PRUint64 timeout = DEFAULT_PROTOCOL_TIMEOUT; - Replica *replica = NULL; if ((timeout = agmt_get_protocol_timeout(prp->agmt)) == 0) { timeout = DEFAULT_PROTOCOL_TIMEOUT; - if (prp->replica_object) { - replica = object_get_data(prp->replica_object); - if ((timeout = replica_get_protocol_timeout(replica)) == 0) { + if (prp->replica) { + if ((timeout = replica_get_protocol_timeout(prp->replica)) == 0) { timeout = DEFAULT_PROTOCOL_TIMEOUT; } } @@ -729,7 +727,7 @@ Repl_5_Tot_Protocol_new(Repl_Protocol *rp) prp->repl50consumer = 0; prp->repl71consumer = 0; prp->repl90consumer = 0; - prp->replica_object = prot_get_replica_object(rp); + prp->replica = prot_get_replica(rp); return prp; loser: repl5_tot_delete(&prp); diff --git a/ldap/servers/plugins/replication/repl_connext.c b/ldap/servers/plugins/replication/repl_connext.c index 6b88dee..19cb396 100644 --- a/ldap/servers/plugins/replication/repl_connext.c +++ b/ldap/servers/plugins/replication/repl_connext.c @@ -62,7 +62,7 @@ consumer_connection_extension_destructor(void *ext, void *object __attribute__(( */ consumer_connection_extension *connext = (consumer_connection_extension *)ext; if (NULL != connext->replica_acquired) { - Replica *r = object_get_data((Object *)connext->replica_acquired); + Replica *r = connext->replica_acquired; /* If a total update was in progress, abort it */ if (REPL_PROTOCOL_50_TOTALUPDATE == connext->repl_protocol_version) { Slapi_PBlock *pb = slapi_pblock_new(); @@ -89,7 +89,6 @@ consumer_connection_extension_destructor(void *ext, void *object __attribute__(( replica_set_tombstone_reap_stop(r, PR_FALSE); } replica_relinquish_exclusive_access(r, connid, -1); - object_release((Object *)connext->replica_acquired); connext->replica_acquired = NULL; } diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c index 5bed849..14c8e0b 100644 --- a/ldap/servers/plugins/replication/repl_extop.c +++ b/ldap/servers/plugins/replication/repl_extop.c @@ -44,7 +44,6 @@ * */ static int check_replica_id_uniqueness(Replica *replica, RUV *supplier_ruv); -static multimaster_mtnode_extension *replica_config_get_mtnode_by_dn(const char *dn); static int encode_ruv(BerElement *ber, const RUV *ruv) @@ -88,7 +87,7 @@ create_ReplicationExtopPayload(const char *protocol_oid, struct berval *req_data = NULL; BerElement *tmp_bere = NULL; int rc = 0; - Object *repl_obj = NULL, *ruv_obj = NULL; + Object *ruv_obj = NULL; Replica *repl; RUV *ruv; Slapi_DN *sdn = NULL; @@ -115,14 +114,12 @@ create_ReplicationExtopPayload(const char *protocol_oid, } sdn = slapi_sdn_new_dn_byref(repl_root); - repl_obj = replica_get_replica_from_dn(sdn); - if (repl_obj == NULL) { + repl = replica_get_replica_from_dn(sdn); + if (repl == NULL) { rc = LDAP_OPERATIONS_ERROR; goto loser; } - repl = (Replica *)object_get_data(repl_obj); - PR_ASSERT(repl); ruv_obj = replica_get_ruv(repl); if (ruv_obj == NULL) { rc = LDAP_OPERATIONS_ERROR; @@ -208,9 +205,6 @@ done: if (NULL != sdn) { slapi_sdn_free(&sdn); /* Put on stack instead of allocating? */ } - if (NULL != repl_obj) { - object_release(repl_obj); - } if (NULL != ruv_obj) { object_release(ruv_obj); } @@ -522,7 +516,6 @@ multimaster_extop_StartNSDS50ReplicationRequest(Slapi_PBlock *pb) char *repl_root = NULL; Slapi_DN *repl_root_sdn = NULL; char **referrals = NULL; - Object *replica_object = NULL; Replica *replica = NULL; void *conn; consumer_connection_extension *connext = NULL; @@ -665,10 +658,7 @@ multimaster_extop_StartNSDS50ReplicationRequest(Slapi_PBlock *pb) goto send_response; } - replica_object = replica_get_replica_from_dn(repl_root_sdn); - if (NULL != replica_object) { - replica = object_get_data(replica_object); - } + replica = replica_get_replica_from_dn(repl_root_sdn); if (NULL == replica) { response = NSDS50_REPL_NO_SUCH_REPLICA; goto send_response; @@ -769,8 +759,7 @@ multimaster_extop_StartNSDS50ReplicationRequest(Slapi_PBlock *pb) } else { locking_purl = NULL; /* no dangling pointers */ /* Stick the replica object pointer in the connection extension */ - connext->replica_acquired = (void *)replica_object; - replica_object = NULL; + connext->replica_acquired = replica; } /* remove this code once ticket 374 is fixed */ @@ -1007,7 +996,7 @@ send_response: * replica had been acquired, so we'd better release it. */ if (NULL != connext && NULL != connext->replica_acquired) { - Replica *r = (Replica *)object_get_data((Object *)connext->replica_acquired); + Replica *r = connext->replica_acquired; uint64_t r_locking_conn; /* At this point the supplier runs a Replica Agreement for @@ -1033,7 +1022,6 @@ send_response: if ((r_locking_conn != ULONG_MAX) && (r_locking_conn == connid)) { replica_relinquish_exclusive_access(r, connid, opid); - object_release((Object *)connext->replica_acquired); connext->replica_acquired = NULL; } } @@ -1056,10 +1044,6 @@ send_response: } slapi_pblock_set(pb, SLAPI_CONN_IS_REPLICATION_SESSION, &zero); } - /* Release reference to replica_object */ - if (NULL != replica_object) { - object_release(replica_object); - } /* bind_sdn */ if (NULL != bind_sdn) { slapi_sdn_free(&bind_sdn); @@ -1137,7 +1121,7 @@ multimaster_extop_EndNSDS50ReplicationRequest(Slapi_PBlock *pb) connext = consumer_connection_extension_acquire_exclusive_access(conn, connid, opid); if (NULL != connext && NULL != connext->replica_acquired) { int zero = 0; - Replica *r = (Replica *)object_get_data((Object *)connext->replica_acquired); + Replica *r = connext->replica_acquired; /* if this is total protocol we need to install suppliers ruv for the replica */ if (connext->repl_protocol_version == REPL_PROTOCOL_50_TOTALUPDATE) { @@ -1206,7 +1190,6 @@ multimaster_extop_EndNSDS50ReplicationRequest(Slapi_PBlock *pb) /* Relinquish control of the replica */ replica_relinquish_exclusive_access(r, connid, opid); - object_release((Object *)connext->replica_acquired); connext->replica_acquired = NULL; connext->isreplicationsession = 0; slapi_pblock_set(pb, SLAPI_CONN_IS_REPLICATION_SESSION, &zero); @@ -1256,27 +1239,6 @@ free_and_return: } /* - * Return the mtnode extension of the dn - */ -static multimaster_mtnode_extension * -replica_config_get_mtnode_by_dn(const char *dn) -{ - Slapi_DN *sdn; - mapping_tree_node *mtnode; - multimaster_mtnode_extension *ext = NULL; - - sdn = slapi_sdn_new_dn_byval(dn); - mtnode = slapi_get_mapping_tree_node_by_dn(sdn); - if (mtnode) { - /* check if the replica object already exists in the subtree */ - ext = (multimaster_mtnode_extension *)repl_con_get_ext(REPL_CON_EXT_MTNODE, mtnode); - } - slapi_sdn_free(&sdn); - - return ext; -} - -/* * Decode the ber element passed to us by the cleanAllRUV task */ int @@ -1322,8 +1284,6 @@ free_and_return: int multimaster_extop_abort_cleanruv(Slapi_PBlock *pb) { - multimaster_mtnode_extension *mtnode_ext = NULL; - int release_it = 0; PRThread *thread = NULL; cleanruv_data *data; Replica *r; @@ -1365,29 +1325,9 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb) rid); } /* - * Get the node, so we can get the replica and its agreements + * Get the replica */ - if ((mtnode_ext = replica_config_get_mtnode_by_dn(repl_root)) == NULL) { - slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "multimaster_extop_abort_cleanruv - " - "Abort CleanAllRUV Task - Failed to get replication node " - "from (%s), aborting operation\n", - repl_root); - rc = LDAP_OPERATIONS_ERROR; - goto out; - } - if (mtnode_ext->replica) { - object_acquire(mtnode_ext->replica); - release_it = 1; - } else { - slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "multimaster_extop_abort_cleanruv - " - "Abort CleanAllRUV Task - Replica is missing from (%s), " - "aborting operation\n", - repl_root); - rc = LDAP_OPERATIONS_ERROR; - goto out; - } - r = (Replica *)object_get_data(mtnode_ext->replica); - if (r == NULL) { + if ((r = replica_get_replica_from_root(repl_root)) == NULL) { slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "multimaster_extop_abort_cleanruv - " "Abort CleanAllRUV Task - Replica is NULL, aborting task\n"); rc = LDAP_OPERATIONS_ERROR; @@ -1410,8 +1350,6 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb) rc = LDAP_OPERATIONS_ERROR; goto out; } - data->repl_obj = mtnode_ext->replica; /* released in replica_abort_task_thread() */ - release_it = 0; /* thread owns it now */ data->replica = r; data->task = NULL; data->payload = slapi_ch_bvdup(extop_payload); @@ -1434,7 +1372,6 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb) slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "multimaster_extop_abort_cleanruv - " "Abort CleanAllRUV Task - Unable to create abort " "thread. Aborting task.\n"); - release_it = 1; /* have to release mtnode_ext->replica now */ slapi_ch_free_string(&data->repl_root); slapi_ch_free_string(&data->certify); ber_bvfree(data->payload); @@ -1443,9 +1380,6 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb) } out: - if (release_it && mtnode_ext && mtnode_ext->replica) { - object_release(mtnode_ext->replica); - } slapi_ch_free_string(&payload); return rc; @@ -1465,9 +1399,8 @@ out: int multimaster_extop_cleanruv(Slapi_PBlock *pb) { - multimaster_mtnode_extension *mtnode_ext = NULL; PRThread *thread = NULL; - Replica *r = NULL; + Replica *replica = NULL; cleanruv_data *data = NULL; CSN *maxcsn = NULL; struct berval *extop_payload; @@ -1479,7 +1412,6 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb) char *extop_oid; char *repl_root; char *iter = NULL; - int release_it = 0; int rid = 0; int rc = LDAP_OPERATIONS_ERROR; @@ -1519,25 +1451,9 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb) /* * Get the node, so we can get the replica and its agreements */ - if ((mtnode_ext = replica_config_get_mtnode_by_dn(repl_root)) == NULL) { - slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "multimaster_extop_cleanruv - CleanAllRUV Task - Failed to get replication node " - "from (%s), aborting operation\n", - repl_root); - goto free_and_return; - } + replica = replica_get_replica_from_root(repl_root); - if (mtnode_ext->replica) { - object_acquire(mtnode_ext->replica); - release_it = 1; - } else { - slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "multimaster_extop_cleanruv - CleanAllRUV Task - Replica is missing from (%s), " - "aborting operation\n", - repl_root); - goto free_and_return; - } - - r = (Replica *)object_get_data(mtnode_ext->replica); - if (r == NULL) { + if (replica == NULL) { slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "multimaster_extop_cleanruv - CleanAllRUV Task - Replica is NULL, aborting task\n"); goto free_and_return; } @@ -1549,11 +1465,9 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb) goto free_and_return; } - if (replica_get_type(r) != REPLICA_TYPE_READONLY) { + if (replica_get_type(replica) != REPLICA_TYPE_READONLY) { /* * Launch the cleanruv monitoring thread. Once all the replicas are cleaned it will release the rid - * - * This will also release mtnode_ext->replica */ cleanruv_log(NULL, rid, CLEANALLRUV_ID, SLAPI_LOG_ERR, "Launching cleanAllRUV thread...\n"); @@ -1563,8 +1477,7 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb) "cleanruv_Data\n"); goto free_and_return; } - data->repl_obj = mtnode_ext->replica; - data->replica = r; + data->replica = replica; data->rid = rid; data->task = NULL; data->maxcsn = maxcsn; @@ -1585,7 +1498,6 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb) slapi_ch_free_string(&data->repl_root); slapi_ch_free((void **)&data); } else { - release_it = 0; /* thread will release data->repl_obj == mtnode_ext->replica */ maxcsn = NULL; /* thread owns it now */ rc = LDAP_SUCCESS; } @@ -1596,7 +1508,7 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb) Object *ruv_obj; const RUV *ruv; - ruv_obj = replica_get_ruv(r); + ruv_obj = replica_get_ruv(replica); ruv = object_get_data(ruv_obj); while (!is_task_aborted(rid) && !slapi_is_shutting_down()) { @@ -1623,7 +1535,7 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb) /* * Clean the ruv */ - replica_execute_cleanruv_task_ext(mtnode_ext->replica, rid); + replica_execute_cleanruv_task_ext(replica, rid); /* free everything */ object_release(ruv_obj); @@ -1637,9 +1549,6 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb) } free_and_return: - if (release_it && mtnode_ext && mtnode_ext->replica) { - object_release(mtnode_ext->replica); - } csn_free(&maxcsn); slapi_ch_free_string(&payload); diff --git a/ldap/servers/plugins/replication/repl_objset.c b/ldap/servers/plugins/replication/repl_objset.c deleted file mode 100644 index 7febaac..0000000 --- a/ldap/servers/plugins/replication/repl_objset.c +++ /dev/null @@ -1,497 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -#include -#endif - - -/* repl_objset.c */ -/* - * Support for lifetime management of sets of objects. - * Objects are refcounted. NOTE: this API is deprecated. - * Use the object/objset API provided by libslapd. - */ - -#include "slapi-plugin.h" -#include "slapi-private.h" -#include "repl_objset.h" -#include - -#define REPL_OBJSET_OBJ_FLAG_DELETED 0x1 - - -typedef struct repl_objset_object -{ - void *data; /* pointer to actual node data */ - char *key; /* key for this object. null-terminated string */ - int refcnt; /* reference count for this object */ - unsigned long flags; /* state of this object */ -} Repl_Objset_object; - -typedef struct repl_objset -{ - LList *objects; - FNFree destructor; /* destructor for objects - provided by caller */ - PRLock *lock; -} repl_objset; - - -/* Forward declarations */ -static void removeObjectNolock(Repl_Objset *o, Repl_Objset_object *co); -static Repl_Objset_object *removeCurrentObjectAndGetNextNolock(Repl_Objset *o, - Repl_Objset_object *co, - void *iterator); - -/* - * Create a new set. - * - * Arguments: - * destructor: a function to be called when an object is to be destroyed - * - * Returns: - * A pointer to the object set, or NULL if an error occured. - */ -Repl_Objset * -repl_objset_new(FNFree destructor) -{ - Repl_Objset *p; - - p = (Repl_Objset *)slapi_ch_malloc(sizeof(Repl_Objset)); - p->lock = PR_NewLock(); - if (NULL == p->lock) { - slapi_ch_free((void **)&p); - } - p->objects = llistNew(); - p->destructor = destructor; - return p; -} - - -/* - * Destroy a Repl_Objset. - * Arguments: - * o: the object set to be destroyed - * maxwait: the maximum time to wait for all object refcnts to - * go to zero. - * panic_fn: a function to be called if, after waiting "maxwait" - * seconds, not all object refcnts are zero. - * The caller must ensure that no one else holds references to the - * set or any objects it contains. - */ -void -repl_objset_destroy(Repl_Objset **o, time_t maxwait, FNFree panic_fn) -{ - Repl_Objset_object *co = NULL; - time_t now, stop_time; - int really_gone; - int loopcount; - void *cookie; - - PR_ASSERT(NULL != o); - PR_ASSERT(NULL != *o); - - now = slapi_current_utc_time(); - stop_time = now + maxwait; - - /* - * Loop over the objects until they all are actually gone, - * or until maxwait seconds have passed. - */ - really_gone = 0; - loopcount = 0; - - while (now < stop_time) { - void *cookie; - - PR_Lock((*o)->lock); - - if ((co = llistGetFirst((*o)->objects, &cookie)) == NULL) { - really_gone = 1; - PR_Unlock((*o)->lock); - break; - } - while (NULL != co) { - /* Set the deleted flag so the object isn't returned by iterator */ - co->flags |= REPL_OBJSET_OBJ_FLAG_DELETED; - if (0 == co->refcnt) { - /* Remove the object */ - co = removeCurrentObjectAndGetNextNolock((*o), co, cookie); - - } else - co = llistGetNext((*o)->objects, &cookie); - } - PR_Unlock((*o)->lock); - now = slapi_current_utc_time(); - if (loopcount > 0) { - DS_Sleep(PR_TicksPerSecond()); - } - loopcount++; - } - - if (!really_gone) { - if (NULL != panic_fn) { - /* - * Call the "aargh, this thing won't go away" panic - * function for each remaining object. - */ - PR_Lock((*o)->lock); - co = llistGetFirst((*o)->objects, &cookie); - while (NULL != co) { - panic_fn(co->data); - co = llistGetNext((*o)->objects, &cookie); - } - PR_Unlock((*o)->lock); - } - } else { - /* Free the linked list */ - llistDestroy(&(*o)->objects, (*o)->destructor); - PR_DestroyLock((*o)->lock); - slapi_ch_free((void **)o); - } -} - - -/* - * Add an object to an object set. - * - * Arguments: - * o: The object set to which the object is to be added. - * name: a null-terminated string that names the object. Must - * be unique. - * obj: pointer to the object to be added. - * - * Return codes: - * REPL_OBJSET_SUCCESS: the item was added to the object set - * REPL_OBJSET_DUPLICATE_KEY: an item with the same key is already - * in the object set. - * REPL_OBJSET_INTERNAL_ERROR: something bad happened. - */ -int -repl_objset_add(Repl_Objset *o, const char *name, void *obj) -{ - Repl_Objset_object *co = NULL; - Repl_Objset_object *tmp = NULL; - int rc = REPL_OBJSET_SUCCESS; - - PR_ASSERT(NULL != o); - PR_ASSERT(NULL != name); - PR_ASSERT(NULL != obj); - - PR_Lock(o->lock); - tmp = llistGet(o->objects, name); - if (NULL != tmp) { - rc = REPL_OBJSET_DUPLICATE_KEY; - goto loser; - } - co = (Repl_Objset_object *)slapi_ch_malloc(sizeof(Repl_Objset_object)); - co->data = obj; - co->key = slapi_ch_strdup(name); - co->refcnt = 0; - co->flags = 0UL; - if (llistInsertHead(o->objects, name, co) != 0) { - rc = REPL_OBJSET_INTERNAL_ERROR; - goto loser; - } - PR_Unlock(o->lock); - return rc; - -loser: - PR_Unlock(o->lock); - if (NULL != co) { - if (NULL != co->key) { - slapi_ch_free((void **)&co->key); - } - slapi_ch_free((void **)&co); - } - return rc; -} - - -/* Must be called with the repl_objset locked */ -static void -removeObjectNolock(Repl_Objset *o, Repl_Objset_object *co) -{ - /* Remove from list */ - llistRemove(o->objects, co->key); - /* Destroy the object */ - o->destructor(&(co->data)); - slapi_ch_free((void **)&(co->key)); - /* Deallocate the container */ - slapi_ch_free((void **)&co); -} - -static Repl_Objset_object * -removeCurrentObjectAndGetNextNolock(Repl_Objset *o, Repl_Objset_object *co, void *iterator) -{ - Repl_Objset_object *ro; - - PR_ASSERT(o); - PR_ASSERT(co); - PR_ASSERT(iterator); - - ro = llistRemoveCurrentAndGetNext(o->objects, &iterator); - - o->destructor(&(co->data)); - slapi_ch_free((void **)&(co->key)); - /* Deallocate the container */ - slapi_ch_free((void **)&co); - - return ro; -} - -/* Must be called with the repl_objset locked */ -static void -acquireNoLock(Repl_Objset_object *co) -{ - co->refcnt++; -} - - -/* Must be called with the repl_objset locked */ -static void -releaseNoLock(Repl_Objset *o, Repl_Objset_object *co) -{ - PR_ASSERT(co->refcnt >= 1); - if (--co->refcnt == 0) { - if (co->flags & REPL_OBJSET_OBJ_FLAG_DELETED) { - /* Remove the object */ - removeObjectNolock(o, co); - } - } -} - -/* - * Retrieve an object from the object set. If an object with - * the given key is found, its reference count is incremented, - * a pointer to the object is returned, and a handle to use - * to refer to the object is returned. - * - * Arguments: - * o: The object set to be searched. - * key: key of the object to be retrieved - * obj: pointer to void * that will be set to point to the - * object, if found. - * handle: pointer to void * that will be set to point to a - * handle, used to refer to the object, if found. - * - * Returns: - * REPL_OBJSET_SUCCESS: an item was found. - * REPL_OBJSET_KEY_NOT_FOUND: no item with the given key was found. - */ -int -repl_objset_acquire(Repl_Objset *o, const char *key, void **obj, void **handle) -{ - Repl_Objset_object *co = NULL; - int rc = REPL_OBJSET_KEY_NOT_FOUND; - - PR_ASSERT(NULL != o); - PR_ASSERT(NULL != key); - PR_ASSERT(NULL != obj); - PR_ASSERT(NULL != handle); - - PR_Lock(o->lock); - co = llistGet(o->objects, key); - if (NULL != co && !(co->flags & REPL_OBJSET_OBJ_FLAG_DELETED)) { - acquireNoLock(co); - *obj = (void *)co->data; - *handle = (void *)co; - rc = REPL_OBJSET_SUCCESS; - } - PR_Unlock(o->lock); - return rc; -} - - -/* - * Return an object to the object set. - * - * Arguments: - * o: The object set containing the objct - * handle: reference to the object. - * - */ -void -repl_objset_release(Repl_Objset *o, void *handle) -{ - Repl_Objset_object *co; - - PR_ASSERT(NULL != o); - PR_ASSERT(NULL != handle); - - co = (Repl_Objset_object *)handle; - PR_Lock(o->lock); - releaseNoLock(o, co); - PR_Unlock(o->lock); -} - - -/* - * Delete an object from the object set - * - * Arguments: - * o: The object set containing the object. - * handle: reference to the object. - */ -void -repl_objset_delete(Repl_Objset *o, void *handle) -{ - Repl_Objset_object *co = (Repl_Objset_object *)handle; - - PR_ASSERT(NULL != o); - PR_ASSERT(NULL != co); - - PR_Lock(o->lock); - if (co->refcnt == 0) { - removeObjectNolock(o, co); - } else { - /* Set deleted flag, clean up later */ - co->flags |= REPL_OBJSET_OBJ_FLAG_DELETED; - } - PR_Unlock(o->lock); -} - - -typedef struct _iterator -{ - Repl_Objset *o; /* set for which iterator was created */ - void *cookie; /* for linked list */ - Repl_Objset_object *co; /* our wrapper */ -} iterator; - -/* - * Get the first object in an object set. - * Used when enumerating all of the objects in a set. - * Arguments: - * o: The object set being enumerated - * itcontext: an iteration context, to be passed back to subsequent calls - * to repl_objset_next_object. - * handle: a pointer to pointer to void. This will be filled in with - * a reference to the object's enclosing object. - * Returns: - * A pointer to the next object in the set, or NULL if there are no - * objects in the set. - * - */ -void * -repl_objset_first_object(Repl_Objset *o, void **itcontext, void **handle) -{ - Repl_Objset_object *co = NULL; - void *cookie; - void *retptr = NULL; - iterator *it; - - PR_ASSERT(NULL != o); - PR_ASSERT(NULL != itcontext); - - *itcontext = NULL; - - if (NULL == o->objects) { - return (NULL); - } - - /* Find the first non-deleted object */ - PR_Lock(o->lock); - co = llistGetFirst(o->objects, &cookie); - while (NULL != co && (co->flags & REPL_OBJSET_OBJ_FLAG_DELETED)) { - co = llistGetNext(o->objects, &cookie); - } - - if (NULL != co) { - /* Increment refcnt until item given back to us */ - acquireNoLock(co); - - /* Save away context */ - it = (iterator *)slapi_ch_malloc(sizeof(iterator)); - *itcontext = it; - it->o = o; - it->cookie = cookie; - it->co = co; - retptr = co->data; - } - - PR_Unlock(o->lock); - if (NULL != handle) { - *handle = co; - } - - return retptr; -} - - -/* - * Get the next object in the set. - * Arguments: - * o: The object set being enumerated - * itcontext: an iteration context, to be passed back to subsequent calls - * to repl_objset_next_object. - * handle: a pointer to pointer to void. This will be filled in with - * a reference to the object's enclosing object. - * - * Returns: - * A pointer to the next object in the set, or NULL if there are no more - * objects. - */ -void * -repl_objset_next_object(Repl_Objset *o, void *itcontext, void **handle) -{ - Repl_Objset_object *co = NULL; - Repl_Objset_object *tmp_co; - void *retptr = NULL; - iterator *it = (iterator *)itcontext; - - PR_ASSERT(NULL != o); - PR_ASSERT(NULL != it); - PR_ASSERT(NULL != it->co); - - PR_Lock(o->lock); - tmp_co = it->co; - - /* Find the next non-deleted object */ - while ((co = llistGetNext(o->objects, &it->cookie)) != NULL && - !(co->flags & REPL_OBJSET_OBJ_FLAG_DELETED)) - ; - - if (NULL != co) { - acquireNoLock(co); - it->co = co; - retptr = co->data; - } else { - /* - * No more non-deleted objects - erase context (freeing - * it is responsibility of caller. - */ - it->cookie = NULL; - it->co = NULL; - } - releaseNoLock(o, tmp_co); - PR_Unlock(o->lock); - if (NULL != handle) { - *handle = co; - } - return retptr; -} - - -/* - * Destroy an itcontext iterator - */ -void -repl_objset_iterator_destroy(void **itcontext) -{ - if (NULL != itcontext && NULL != *itcontext) { - /* check if we did not iterate through the entire list - and need to release last accessed element */ - iterator *it = *(iterator **)itcontext; - if (it->co) - repl_objset_release(it->o, it->co); - - slapi_ch_free((void **)itcontext); - } -} diff --git a/ldap/servers/plugins/replication/repl_objset.h b/ldap/servers/plugins/replication/repl_objset.h deleted file mode 100644 index 04b9885..0000000 --- a/ldap/servers/plugins/replication/repl_objset.h +++ /dev/null @@ -1,45 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -/* - */ - -/* repl_objset.h */ -/* - * Support for lifetime management of sets of objects. - * Objects are refcounted. NOTE: This API should go away - * in favor of the objset API provided by libslapd. - */ -#ifndef _REPL_OBJSET_H -#define __REPL_OBJSET_H - -#include "llist.h" - -#define REPL_OBJSET_SUCCESS 0 -#define REPL_OBJSET_DUPLICATE_KEY 1 -#define REPL_OBJSET_INTERNAL_ERROR 2 -#define REPL_OBJSET_KEY_NOT_FOUND 3 - -typedef struct repl_objset Repl_Objset; - -Repl_Objset *repl_objset_new(FNFree destructor); -void repl_objset_destroy(Repl_Objset **o, time_t maxwait, FNFree panic_fn); -int repl_objset_add(Repl_Objset *o, const char *name, void *obj); -int repl_objset_acquire(Repl_Objset *o, const char *key, void **obj, void **handle); -void repl_objset_release(Repl_Objset *o, void *handle); -void repl_objset_delete(Repl_Objset *o, void *handle); -void *repl_objset_next_object(Repl_Objset *o, void *cookie, void **handle); -void *repl_objset_first_object(Repl_Objset *o, void **cookie, void **handle); -void repl_objset_iterator_destroy(void **itcontext); - -#endif /* _REPL_OBJSET_H */ diff --git a/ldap/servers/plugins/replication/windows_inc_protocol.c b/ldap/servers/plugins/replication/windows_inc_protocol.c index 853467e..1c07534 100644 --- a/ldap/servers/plugins/replication/windows_inc_protocol.c +++ b/ldap/servers/plugins/replication/windows_inc_protocol.c @@ -462,7 +462,6 @@ windows_inc_run(Private_Repl_Protocol *prp) /* ONREPL - at this state we unconditionally acquire the replica ignoring all events. Not sure if this is good */ - object_acquire(prp->replica_object); rc = windows_acquire_replica(prp, &ruv, (run_dirsync == 0) /* yes, check the consumer RUV for incremental, but not if we're going to dirsync afterwards */); @@ -492,7 +491,6 @@ windows_inc_run(Private_Repl_Protocol *prp) prp->last_acquire_response_code, NULL); } - object_release(prp->replica_object); break; case STATE_BACKOFF_START: @@ -701,10 +699,8 @@ windows_inc_run(Private_Repl_Protocol *prp) case EXAMINE_RUV_OK: /* update our csn generator state with the consumer's ruv data */ dev_debug("windows_inc_run(STATE_SENDING_UPDATES) -> windows_examine_update_vector OK"); - object_acquire(prp->replica_object); - replica = object_get_data(prp->replica_object); + replica = prp->replica; rc = replica_update_csngen_state(replica, ruv); - object_release(prp->replica_object); replica = NULL; if (rc == CSN_LIMIT_EXCEEDED) /* too much skew */ { @@ -1432,7 +1428,7 @@ Windows_Inc_Protocol_new(Repl_Protocol *rp) prp->notify_window_opened = windows_inc_notify_window_opened; prp->notify_window_closed = windows_inc_notify_window_closed; prp->update_now = windows_inc_update_now; - prp->replica_object = prot_get_replica_object(rp); + prp->replica = prot_get_replica(rp); if ((prp->lock = PR_NewLock()) == NULL) { goto loser; } @@ -1510,12 +1506,9 @@ windows_examine_update_vector(Private_Repl_Protocol *prp, RUV *remote_ruv) char *remote_gen = ruv_get_replica_generation(remote_ruv); Object *local_ruv_obj; RUV *local_ruv; - Replica *replica; - PR_ASSERT(NULL != prp->replica_object); - replica = object_get_data(prp->replica_object); - PR_ASSERT(NULL != replica); - local_ruv_obj = replica_get_ruv(replica); + PR_ASSERT(NULL != prp->replica); + local_ruv_obj = replica_get_ruv(prp->replica); if (NULL != local_ruv_obj) { local_ruv = (RUV *)object_get_data(local_ruv_obj); PR_ASSERT(local_ruv); diff --git a/ldap/servers/plugins/replication/windows_protocol_util.c b/ldap/servers/plugins/replication/windows_protocol_util.c index 0ee737f..0d287fd 100644 --- a/ldap/servers/plugins/replication/windows_protocol_util.c +++ b/ldap/servers/plugins/replication/windows_protocol_util.c @@ -567,8 +567,7 @@ windows_acquire_replica(Private_Repl_Protocol *prp, RUV **ruv, int check_ruv) ruv_destroy(ruv); } - object_acquire(prp->replica_object); - replica = object_get_data(prp->replica_object); + replica = prp->replica; supl_ruv_obj = replica_get_ruv(replica); cons_ruv_obj = agmt_get_consumer_ruv(prp->agmt); @@ -590,7 +589,6 @@ windows_acquire_replica(Private_Repl_Protocol *prp, RUV **ruv, int check_ruv) object_release(supl_ruv_obj); if (cons_ruv_obj) object_release(cons_ruv_obj); - object_release(prp->replica_object); replica = NULL; /* Once we get here we have a valid ruv */ diff --git a/ldap/servers/plugins/replication/windows_tot_protocol.c b/ldap/servers/plugins/replication/windows_tot_protocol.c index 7bc451f..da244c1 100644 --- a/ldap/servers/plugins/replication/windows_tot_protocol.c +++ b/ldap/servers/plugins/replication/windows_tot_protocol.c @@ -120,7 +120,6 @@ windows_tot_run(Private_Repl_Protocol *prp) callback_data cb_data; RUV *ruv = NULL; RUV *starting_ruv = NULL; - Replica *replica = NULL; Object *local_ruv_obj = NULL; int one_way; @@ -189,8 +188,7 @@ windows_tot_run(Private_Repl_Protocol *prp) * the incremental sync protocol ( send_updates() ). We will * use this value for setting the consumer RUV if the total * update succeeds. */ - replica = object_get_data(prp->replica_object); - local_ruv_obj = replica_get_ruv(replica); + local_ruv_obj = replica_get_ruv(prp->replica); starting_ruv = ruv_dup((RUV *)object_get_data(local_ruv_obj)); object_release(local_ruv_obj); @@ -339,7 +337,7 @@ Windows_Tot_Protocol_new(Repl_Protocol *rp) prp->notify_agmt_changed = windows_tot_noop; prp->notify_window_opened = windows_tot_noop; prp->notify_window_closed = windows_tot_noop; - prp->replica_object = prot_get_replica_object(rp); + prp->replica = prot_get_replica(rp); prp->update_now = windows_tot_noop; if ((prp->lock = PR_NewLock()) == NULL) { goto loser; diff --git a/ldap/servers/slapd/add.c b/ldap/servers/slapd/add.c index 6eb69e3..06ca1ee 100644 --- a/ldap/servers/slapd/add.c +++ b/ldap/servers/slapd/add.c @@ -594,6 +594,8 @@ op_shared_add(Slapi_PBlock *pb) if (err) { valuearray_free(&unhashed_password_vals); } + } else { + valuearray_free(&unhashed_password_vals); } #if defined(THISISTEST) diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c index 93370b7..ce8be3e 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_add.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c @@ -745,6 +745,7 @@ ldbm_back_add(Slapi_PBlock *pb) SLAPI_ATTR_VALUE_PARENT_UNIQUEID, operation->o_params.p.p_add.parentuniqueid); } + slapi_sdn_done(&nscpEntrySDN); } else { /* if an entry is explicitely added as tombstone the entry flag has to be set */ if (slapi_entry_attr_hasvalue(addingentry->ep_entry, diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c index 52bad1d..9c41efb 100644 --- a/ldap/servers/slapd/daemon.c +++ b/ldap/servers/slapd/daemon.c @@ -1176,6 +1176,14 @@ slapd_daemon(daemon_ports_t *ports, ns_thrpool_t *tp) plugin_closeall(1 /* Close Backends */, 1 /* Close Globals */); + /* + * connection_table_free could use callbacks in the backend. + * (e.g., be_search_results_release) + * Thus, it needs to be called before be_cleanupall. + */ + connection_table_free(the_connection_table); + the_connection_table = NULL; + if (!in_referral_mode) { /* Close SNMP collator after the plugins closed... * Replication plugin still performs internal ops that @@ -1192,14 +1200,6 @@ slapd_daemon(daemon_ports_t *ports, ns_thrpool_t *tp) */ log_access_flush(); - /* - * connection_table_free could use callbacks in the backend. - * (e.g., be_search_results_release) - * Thus, it needs to be called before be_cleanupall. - */ - connection_table_free(the_connection_table); - the_connection_table = NULL; - be_cleanupall(); plugin_dependency_freeall(); connection_post_shutdown_cleanup();