summaryrefslogtreecommitdiffstats
path: root/ldap
diff options
context:
space:
mode:
authorNoriko Hosoi <nhosoi@redhat.com>2010-09-12 21:59:29 -0700
committerNoriko Hosoi <nhosoi@redhat.com>2010-09-13 10:06:51 -0700
commit80ce631a97977c273a56b5d4d7e99a7eaf109d57 (patch)
tree75207bb0b02a57485d87efedabfcc2fe243eeb06 /ldap
parent2a25e6518f6e2bd83dd4750bf023d332edef2063 (diff)
downloadds-80ce631a97977c273a56b5d4d7e99a7eaf109d57.tar.gz
ds-80ce631a97977c273a56b5d4d7e99a7eaf109d57.tar.xz
ds-80ce631a97977c273a56b5d4d7e99a7eaf109d57.zip
Bug 633168 - Share backend dbEnv with the replication changelog
https://bugzilla.redhat.com/show_bug.cgi?id=633168 Description: * cl5_api.c, cl5_api.h - fetches dbEnv from backend using slapi_back_get_info. - unused macros and DB helper functions and APIs are removed. * cl5_config.c - local changelog DB related config parameters are removed. * Added SLAPI_PLUGIN_BE_PRE_CLOSE_FN and SLAPI_PLUGIN_BE_POST_OPEN_FN to close changelog DB before dbEnv is closed and to open changelog DB after dbEnv is opened, respectively. * Added slapi APIs slapi_back_get_info and slapi_back_set_info to get/set the backend info. * back-ldbm - db2bak[.pl] and bak2db[.pl] backs up and restores the database files including changelog db. - changelog dir is backed up in <backupdir>/.repl_changelog_backup. - underlying implementation ldbm_back_get_info for slapi_back_get_info is added. * Added an upgrade script 81changelog.pl See also: http://directory.fedoraproject.org/wiki/Move_changelog
Diffstat (limited to 'ldap')
-rw-r--r--ldap/servers/plugins/replication/cl5_api.c1245
-rw-r--r--ldap/servers/plugins/replication/cl5_api.h77
-rw-r--r--ldap/servers/plugins/replication/cl5_clcache.c11
-rw-r--r--ldap/servers/plugins/replication/cl5_clcache.h2
-rw-r--r--ldap/servers/plugins/replication/cl5_config.c181
-rw-r--r--ldap/servers/plugins/replication/repl5_init.c6
-rw-r--r--ldap/servers/plugins/replication/repl5_plugins.c10
-rw-r--r--ldap/servers/plugins/replication/repl_extop.c3
-rw-r--r--ldap/servers/slapd/back-ldbm/archive.c45
-rw-r--r--ldap/servers/slapd/back-ldbm/back-ldbm.h4
-rw-r--r--ldap/servers/slapd/back-ldbm/dblayer.c705
-rw-r--r--ldap/servers/slapd/back-ldbm/dblayer.h4
-rw-r--r--ldap/servers/slapd/back-ldbm/import-threads.c37
-rw-r--r--ldap/servers/slapd/back-ldbm/init.c4
-rw-r--r--ldap/servers/slapd/back-ldbm/ldbm_modify.c2
-rw-r--r--ldap/servers/slapd/back-ldbm/ldif2ldbm.c31
-rw-r--r--ldap/servers/slapd/back-ldbm/misc.c26
-rw-r--r--ldap/servers/slapd/back-ldbm/proto-back-ldbm.h5
-rw-r--r--ldap/servers/slapd/backend.c22
-rw-r--r--ldap/servers/slapd/pblock.c37
-rw-r--r--ldap/servers/slapd/plugin.c10
-rw-r--r--ldap/servers/slapd/slap.h10
-rw-r--r--ldap/servers/slapd/slapi-plugin.h39
-rw-r--r--ldap/servers/slapd/slapi-private.h2
24 files changed, 775 insertions, 1743 deletions
diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c
index 8e152b74..79677416 100644
--- a/ldap/servers/plugins/replication/cl5_api.c
+++ b/ldap/servers/plugins/replication/cl5_api.c
@@ -115,17 +115,8 @@
(env)->txn_begin((env), (parent_txn), (tid), (flags))
#define TXN_COMMIT(txn, flags) (txn)->commit((txn), (flags))
#define TXN_ABORT(txn) (txn)->abort(txn)
-#define TXN_CHECKPOINT(env, kbyte, min, flags) \
- (env)->txn_checkpoint((env), (kbyte), (min), (flags))
#define MEMP_STAT(env, gsp, fsp, flags, malloc) \
(env)->memp_stat((env), (gsp), (fsp), (flags))
-#define MEMP_TRICKLE(env, pct, nwrotep) \
- (env)->memp_trickle((env), (pct), (nwrotep))
-#define LOG_ARCHIVE(env, listp, flags, malloc) \
- (env)->log_archive((env), (listp), (flags))
-#define LOG_FLUSH(env, lsn) (env)->log_flush((env), (lsn))
-#define LOCK_DETECT(env, flags, atype, aborted) \
- (env)->lock_detect((env), (flags), (atype), (aborted))
#if DB_VERSION_MINOR >= 4 /* i.e. 4.4 or later */
#define DB_ENV_SET_TAS_SPINS(env, tas_spins) \
(env)->mutex_set_tas_spins((env), (tas_spins))
@@ -142,23 +133,13 @@
txn_begin((env), (parent_txn), (tid), (flags))
#define TXN_COMMIT(txn, flags) txn_commit((txn), (flags))
#define TXN_ABORT(txn) txn_abort((txn))
-#define TXN_CHECKPOINT(env, kbyte, min, flags) \
- txn_checkpoint((env), (kbyte), (min), (flags))
-#define MEMP_TRICKLE(env, pct, nwrotep) memp_trickle((env), (pct), (nwrotep))
-#define LOG_FLUSH(env, lsn) log_flush((env), (lsn))
-#define LOCK_DETECT(env, flags, atype, aborted) \
- lock_detect((env), (flags), (atype), (aborted))
#if 1000*DB_VERSION_MAJOR + 100*DB_VERSION_MINOR >= 3300
#define MEMP_STAT(env, gsp, fsp, flags, malloc) memp_stat((env), (gsp), (fsp))
-#define LOG_ARCHIVE(env, listp, flags, malloc) \
- log_archive((env), (listp), (flags))
#else /* older than db 3.3 */
#define MEMP_STAT(env, gsp, fsp, flags, malloc) \
memp_stat((env), (gsp), (fsp), (malloc))
-#define LOG_ARCHIVE(env, listp, flags, malloc) \
- log_archive((env), (listp), (flags), (malloc))
#endif
#endif
/*
@@ -284,14 +265,9 @@ static int _cl5AppInit (PRBool *didRecovery);
static int _cl5DBOpen ();
static void _cl5SetDefaultDBConfig ();
static void _cl5SetDBConfig (const CL5DBConfig *config);
-static void _cl5InitDBEnv(DB_ENV *dbEnv);
static int _cl5CheckDBVersion ();
static int _cl5ReadDBVersion (const char *dir, char *clVersion, int buflen);
static int _cl5WriteDBVersion ();
-static int _cl5CheckGuardian ();
-static int _cl5ReadGuardian (char *buff);
-static int _cl5WriteGuardian ();
-static int _cl5RemoveGuardian ();
static void _cl5Close ();
static int _cl5Delete (const char *dir, PRBool rmDir);
static void _cl5DBClose ();
@@ -300,9 +276,6 @@ static void _cl5DBClose ();
static int _cl5DispatchDBThreads ();
static int _cl5AddThread ();
static void _cl5RemoveThread ();
-static int _cl5DeadlockMain (void *param);
-static int _cl5CheckpointMain (void *param);
-static int _cl5TrickleMain (void *param);
/* functions that work with individual changelog files */
static int _cl5NewDBFile (const char *replName, const char *replGen, CL5DBFile** dbFile);
@@ -317,7 +290,6 @@ 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 int _cl5CopyDBFiles (const char *srcDir, const char *distDir, Object **replicas);
static char* _cl5Replica2FileName (Object *replica);
static char* _cl5MakeFileName (const char *replName, const char *replGen);
static PRBool _cl5FileName2Replica (const char *fileName, Object **replica);
@@ -369,16 +341,7 @@ static int _cl5ConstructRUV (const char *replGen, Object *obj, PRBool purge);
static int _cl5UpdateRUV (Object *obj, CSN *csn, PRBool newReplica, PRBool purge);
static int _cl5GetRUV2Purge2 (Object *fileObj, RUV **ruv);
-/* db error processing */
-#if 1000*DB_VERSION_MAJOR + 100*DB_VERSION_MINOR >= 4300
-static void _cl5DBLogPrint(const DB_ENV *dbenv, const char* prefix, const char *buffer);
-#else /* assume 42 */
-static void _cl5DBLogPrint(const char* prefix, char *buffer);
-#endif
-
/* bakup/recovery, import/export */
-static PRBool _cl5IsLogFile (const char *name);
-static int _cl5Recover (int open_flags, DB_ENV *dbEnv);
static int _cl5LDIF2Operation (char *ldifEntry, slapi_operation_parameters *op,
char **replGen);
static int _cl5Operation2LDIF (const slapi_operation_parameters *op, const char *replGen,
@@ -393,18 +356,6 @@ static char* _cl5GetHelperEntryKey (int type, char *csnStr);
static Object* _cl5GetReplica (const slapi_operation_parameters *op, const char* replGen);
static int _cl5FileEndsWith(const char *filename, const char *ext);
-/* Callback function for libdb to spit error info into our log */
-#if 1000*DB_VERSION_MAJOR + 100*DB_VERSION_MINOR >= 4300
-static void dblayer_log_print(const DB_ENV *dbenv, const char* prefix,
- const char *buffer)
-#else
-static void dblayer_log_print(const char* prefix, char *buffer)
-#endif
-{
- /* We ignore the prefix since we know who we are anyway */
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl, "libdb: %s\n", buffer);
-}
-
static PRLock *cl5_diskfull_lock = NULL;
static int cl5_diskfull_flag = 0;
@@ -560,7 +511,7 @@ int cl5Open (const char *dir, const CL5DBConfig *config)
else
{
s_cl5Desc.dbState = CL5_STATE_OPEN;
- clcache_set_config((CL5DBConfig *)config);
+ clcache_set_config();
}
done:;
@@ -669,147 +620,6 @@ int cl5Delete (const char *dir)
return rc;
}
-/* Name: cl5OpenDB
- Description: opens changelog file for specified file
- Parameters: replica - replica whose file we wish to open
- Return: CL5_SUCCESS if successful;
- CL5_BAD_STATE if the changelog is not initialized;
- CL5_BAD_DATA - if NULL id is supplied
- */
-int cl5OpenDB (Object *replica)
-{
- int rc;
-
- if (replica == NULL)
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, "cl5OpenDB: null replica\n");
- return CL5_BAD_DATA;
- }
-
- if (s_cl5Desc.dbState == CL5_STATE_NONE)
- {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl,
- "cl5OpenDB: changelog is not initialized\n");
- return CL5_BAD_STATE;
- }
-
- /* make sure that changelog stays open while operation is in progress */
- rc = _cl5AddThread ();
- if (rc != CL5_SUCCESS)
- return rc;
-
- rc = _cl5DBOpenFile (replica, NULL /* file object */, PR_TRUE /* check for duplicates */);
-
- _cl5RemoveThread ();
-
- return rc;
-}
-
-/* Name: cl5CloseDB
- Description: closes changelog file for the specified replica
- Parameters: replica - replica whose file we wish to close
- Return: CL5_SUCCESS if successful;
- CL5_BAD_STATE if the changelog is not initialized;
- CL5_BAD_DATA - if NULL id is supplied
- CL5_NOTFOUND - nothing is known about specified database
- */
-int cl5CloseDB (Object *replica)
-{
- int rc;
- Object *obj;
-
- if (replica == NULL)
- {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl, "cl5CloseDB: null replica\n");
- return CL5_BAD_DATA;
- }
-
- if (s_cl5Desc.dbState == CL5_STATE_NONE)
- {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl,
- "cl5CloseDB: changelog is not initialized\n");
- return CL5_BAD_STATE;
- }
-
- /* make sure that changelog is open while operation is in progress */
- rc = _cl5AddThread ();
- if (rc != CL5_SUCCESS)
- return rc;
-
- rc = _cl5GetDBFile (replica, &obj);
- if (rc == CL5_SUCCESS)
- {
- rc = objset_remove_obj(s_cl5Desc.dbFiles, obj);
- object_release (obj);
- }
- else
- {
- Replica *r;
-
- r = (Replica*)object_get_data (replica);
- PR_ASSERT (r);
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl,
- "cl5CloseDB: failed to close file for replica at (%s)\n",
- slapi_sdn_get_dn (replica_get_root (r)));
- }
-
- _cl5RemoveThread ();
- return rc;
-}
-
-/* Name: cl5DeleteDB
- Description: asynchronously removes changelog file for the specified replica.
- The file is physically removed when it is no longer in use.
- This function is called when a backend is removed or reloaded.
- Parameters: replica - replica whose file we wish to delete
- Return: CL5_SUCCESS if successful;
- CL5_BAD_STATE if the changelog is not initialized;
- CL5_BAD_DATA - if NULL id is supplied
- CL5_NOTFOUND - nothing is known about specified database
- */
-int cl5DeleteDB (Object *replica)
-{
- Object *obj;
- int rc;
-
- if (replica == NULL)
- {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl,
- "cl5DeleteDB: invalid database id\n");
- return CL5_BAD_DATA;
- }
-
- /* changelog is not initialized */
- if (s_cl5Desc.dbState == CL5_STATE_NONE)
- {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl, "cl5DeleteDB: "
- "changelog is not initialized\n");
- 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)
- {
- _cl5DBDeleteFile (obj);
- }
- else
- {
- Replica *r = (Replica*)object_get_data (replica);
- PR_ASSERT (r);
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl, "cl5DeleteDB: "
- "file for replica at (%s) not found\n",
- slapi_sdn_get_dn (replica_get_root (r)));
- }
-
- _cl5RemoveThread ();
- return rc;
-}
-
/* Name: cl5DeleteDBSync
Description: The same as cl5DeleteDB except the function does not return
until the file is removed.
@@ -933,267 +743,6 @@ int cl5GetUpperBoundRUV (Replica *r, RUV **ruv)
return rc;
}
-/* Name: cl5Backup
- Description: makes a backup of the changelog including *.db2,
- log files, and dbversion. Can be called with the changelog in either open or
- closed state.
- Parameters: bkDir - directory to which the data is backed up;
- created if it does not exist
- replicas - optional list of replicas whose changes should be backed up;
- if the list is NULL, entire changelog is backed up.
- Return: CL5_SUCCESS if function is successful;
- CL5_BAD_DATA if invalid directory is passed;
- CL5_BAD_STATE if changelog has not been initialized;
- CL5_DB_ERROR if db call fails;
- CL5_SYSTEM_ERROR if NSPR call or file copy failes.
- */
-int cl5Backup (const char *bkDir, Object **replicas)
-{
- int rc;
- char **list = NULL;
- char **logFile;
- char srcFile [MAXPATHLEN + 1];
- char destFile[MAXPATHLEN + 1];
- DB_TXN *txn = NULL;
-
- if (bkDir == NULL)
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, "cl5Backup: null backup directory\n");
- return CL5_BAD_DATA;
- }
-
- /* changelog must be initialized */
- if (s_cl5Desc.dbState == CL5_STATE_NONE)
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "cl5Backup: changelog is not initialized\n");
- return CL5_BAD_STATE;
- }
-
- /* make sure that changelog stays open while operation is in progress */
- rc = _cl5AddThread ();
- if (rc != CL5_SUCCESS)
- return rc;
-
- /* create backup directory if necessary */
- rc = cl5CreateDirIfNeeded (bkDir);
- if (rc != CL5_SUCCESS)
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "cl5Backup: failed to create backup directory\n");
- goto done;
- }
-
- /* start transaction to tempararily prevent transaction log
- from being trimmed
- */
- rc = TXN_BEGIN(s_cl5Desc.dbEnv, NULL /*pid*/, &txn, 0);
- if (rc != 0)
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "cl5Backup: failed to begin transaction; db error - %d %s\n",
- rc, db_strerror(rc));
- rc = CL5_DB_ERROR;
- goto done;
- }
-
- slapi_log_error(SLAPI_LOG_PLUGIN, repl_plugin_name_cl,
- "cl5Backup: starting changelog backup from %s to %s ...\n", s_cl5Desc.dbDir, bkDir);
-
- /* The following files are backed up: *.<dbext>, log files, dbversion file */
-
- /* copy db file */
- /* ONREPL currently, list of replicas is ignored because db code can't handle
- discrepancy between transaction log and present files; should be fixed before 5.0 ships */
- rc = _cl5CopyDBFiles (s_cl5Desc.dbDir, bkDir, replicas);
- if (rc != CL5_SUCCESS)
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "cl5Backup : failed to copy database files from %s to %s\n", s_cl5Desc.dbDir, bkDir);
- goto done;
- }
-
- /* copy db log files */
- rc = LOG_ARCHIVE(s_cl5Desc.dbEnv, &list, DB_ARCH_LOG, (void *)slapi_ch_malloc);
- if (rc != 0)
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "cl5Backup: failed to get list of log files; db error - %d %s\n",
- rc, db_strerror(rc));
- rc = CL5_SYSTEM_ERROR;
- goto done;
- }
-
- if (list)
- {
- logFile = list;
- while (*logFile)
- {
- PR_snprintf(srcFile, MAXPATHLEN, "%s/%s", s_cl5Desc.dbDir, *logFile);
- PR_snprintf(destFile, MAXPATHLEN, "%s/%s", bkDir, *logFile);
- rc = copyfile(srcFile, destFile, 0, FILE_CREATE_MODE);
- if (rc != 0)
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "cl5Backup: failed to copy %s\n", *logFile);
- rc = CL5_SYSTEM_ERROR;
- goto done;
- }
-
- logFile ++;
- }
-
- slapi_ch_free((void **)&list);
- }
-
- /* now, copy the version file */
- PR_snprintf(srcFile, MAXPATHLEN, "%s/%s", s_cl5Desc.dbDir, VERSION_FILE);
- PR_snprintf(destFile, MAXPATHLEN, "%s/%s", bkDir, VERSION_FILE);
- rc = copyfile(srcFile, destFile, 0, FILE_CREATE_MODE);
- if (rc != 0)
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "cl5Backup: failed to copy %s\n", VERSION_FILE);
- rc = CL5_SYSTEM_ERROR;
- goto done;
- }
-
- rc = CL5_SUCCESS;
- slapi_log_error(SLAPI_LOG_PLUGIN, repl_plugin_name_cl,
- "cl5Backup: changelog backup is finished \n");
-done:;
- if (txn && TXN_ABORT (txn) != 0)
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "cl5Backup: failed to abort transaction; db error - %d %s\n",
- rc, db_strerror(rc));
- rc = CL5_DB_ERROR;
- }
-
- _cl5RemoveThread ();
-
- return rc;
-}
-
-/* Name: cl5Restore
- Description: restores changelog from the backed up copy. Changelog must be ibnitalized and closed.
- Parameters: clDir - changelog dir
- bkDir - directory that contains the backup
- replicas - optional list of replicas whose changes should be recovered;
- if the list is NULL, entire changelog is recovered.
- Return: CL5_SUCCESS if function is successfull;
- CL5_BAD_DATA if invalid parameter is passed;
- CL5_BAD_STATE if changelog is open or not initialized;
- CL5_DB_ERROR if db call fails;
- CL5_SYSTEM_ERROR if NSPR call of file copy fails
- */
-int cl5Restore (const char *clDir, const char *bkDir, Object **replicas)
-{
- int rc;
- char srcFile[MAXPATHLEN + 1];
- char destFile[MAXPATHLEN + 1];
- PRDir *prDir;
- PRDirEntry *prDirEntry;
- int seenLog = 0; /* Tells us if we restored any logfiles */
-
- if (clDir == NULL || bkDir == NULL)
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, "cl5Restore: null parameter\n");
- return CL5_BAD_DATA;
- }
-
- if (s_cl5Desc.dbState == CL5_STATE_NONE)
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "cl5Restore: changelog is not initialized\n");
- return CL5_BAD_STATE;
- }
-
- /* prevent state change while recovery is in progress */
- PR_RWLock_Wlock (s_cl5Desc.stLock);
-
- if (s_cl5Desc.dbState != CL5_STATE_CLOSED)
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "cl5Restore: changelog must be closed\n");
- PR_RWLock_Unlock (s_cl5Desc.stLock);
- return CL5_BAD_STATE;
- }
-
- slapi_log_error(SLAPI_LOG_PLUGIN, repl_plugin_name_cl,
- "cl5Restore: starting changelog recovery from %s to %s ...\n", bkDir, clDir);
-
- /* delete current changelog content */
- rc = _cl5Delete (clDir, PR_FALSE);
- if (rc != CL5_SUCCESS)
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "cl5Restore: failed to remove changelog\n");
- goto done;
- }
-
- /* We copy the files over from the staging area */
- prDir = PR_OpenDir(bkDir);
- if (prDir == NULL)
- {
- rc = CL5_SYSTEM_ERROR;
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "cl5Restore: unable to access backup directory %s; NSPR error - %d\n",
- bkDir, PR_GetError ());
- goto done;
- }
-
- while (NULL != (prDirEntry = PR_ReadDir(prDir, PR_SKIP_DOT | PR_SKIP_DOT_DOT)))
- {
- if (NULL == prDirEntry->name) /* NSPR doesn't behave like the docs say it should */
- {
- break;
- }
-
- /* Log files have names of the form "log.xxxxx". We detect these by looking for
- the prefix "log." and the lack of the ".<dbext>" suffix */
- seenLog |= _cl5IsLogFile(prDirEntry->name);
-
- /* ONREPL currently, list of replicas is ignored because db code can't handle discrepancy
- between transaction log and present files; this should change before 5.0 ships */
- PR_snprintf(destFile, MAXPATHLEN, "%s/%s", clDir, prDirEntry->name);
- PR_snprintf(srcFile, MAXPATHLEN, "%s/%s", bkDir, prDirEntry->name);
- rc = copyfile(srcFile, destFile, 0, FILE_CREATE_MODE);
- if (rc != 0)
- {
- rc = CL5_SYSTEM_ERROR;
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "cl5Restore: failed to copy %s\n", prDirEntry->name);
- PR_CloseDir(prDir);
- goto done;
- }
- }
-
- PR_CloseDir(prDir);
-
- /* now open and close changelog to create all necessary files */
- if (seenLog)
- rc = _cl5Open (clDir, NULL, CL5_OPEN_RESTORE_RECOVER);
- else
- rc = _cl5Open (clDir, NULL, CL5_OPEN_RESTORE);
-
- if (rc == CL5_SUCCESS)
- {
- _cl5Close ();
-
- slapi_log_error(SLAPI_LOG_PLUGIN, repl_plugin_name_cl,
- "cl5Restore: changelog recovery is finished \n");
- }
- else
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "cl5Restore: failed open changelog after recovery\n");
- }
-
-done:;
- PR_RWLock_Unlock (s_cl5Desc.stLock);
- return rc;
-}
/* Name: cl5ExportLDIF
Description: dumps changelog to an LDIF file; changelog can be open or closed.
@@ -1275,7 +824,6 @@ int cl5ExportLDIF (const char *ldifFile, Object **replicas)
obj = objset_next_obj(s_cl5Desc.dbFiles, obj))
{
rc = _cl5ExportFile (prFile, obj);
- object_release (obj);
}
}
@@ -2246,213 +1794,39 @@ int cl5CreateDirIfNeeded (const char *dirName)
return CL5_SUCCESS;
}
-static int _cl5RemoveEnv ()
+static int _cl5AppInit (PRBool *didRecovery)
{
+ int rc = -1; /* initialize to failure */
DB_ENV *dbEnv = NULL;
- int rc = 0;
-
- if ((rc = db_env_create(&dbEnv, 0)) != 0)
- dbEnv = NULL;
-
- if (dbEnv == NULL)
- {
- char *errstr = db_strerror(rc);
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "_cl5RemoveEnv: failed to allocate db environment; "
- "db error - %d %s\n", rc, errstr ? errstr : "unknown");
- return CL5_MEMORY_ERROR;
- }
- rc = dbEnv->remove(dbEnv, s_cl5Desc.dbDir, DB_FORCE);
- if (0 != rc)
- {
- char *errstr = db_strerror(rc);
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "_cl5AppInit: failed to remove db environment; "
- "db error - %d %s\n", rc, errstr ? errstr : "unknown");
- return CL5_DB_ERROR;
- }
- return CL5_SUCCESS;
-}
-
-#ifdef NEED_CL5_REMOVE_LOGS
-static int _cl5RemoveLogs ()
-{
- int rc = CL5_DB_ERROR;
- char filename1[MAXPATHLEN];
- PRDir *dirhandle = NULL;
- dirhandle = PR_OpenDir(s_cl5Desc.dbDir);
- if (NULL != dirhandle) {
- PRDirEntry *direntry = NULL;
- int pre = 0;
- PRFileInfo info;
-
- while (NULL != (direntry =
- PR_ReadDir(dirhandle, PR_SKIP_DOT | PR_SKIP_DOT_DOT)))
- {
- if (NULL == direntry->name) {
- /* NSPR doesn't behave like the docs say it should */
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "_cl5RemoveLogs: PR_ReadDir failed (%d): %s\n",
- PR_GetError(),slapd_pr_strerror(PR_GetError()));
- break;
+ size_t pagesize = 0;
+ char *cookie = NULL;
+ Slapi_Backend *be = slapi_get_first_backend(&cookie);
+ while (be) {
+ rc = slapi_back_get_info(be, BACK_INFO_DBENV, (void **)&dbEnv);
+ if ((LDAP_SUCCESS == rc) && dbEnv) {
+ rc = slapi_back_get_info(be,
+ BACK_INFO_INDEXPAGESIZE, (void **)&pagesize);
+ if ((LDAP_SUCCESS == rc) && pagesize) {
+ break; /* Successfully fetched */
}
- PR_snprintf(filename1, MAXPATHLEN,
- "%s/%s", s_cl5Desc.dbDir, direntry->name);
- pre = PR_GetFileInfo(filename1, &info);
- if (pre == PR_SUCCESS && PR_FILE_DIRECTORY == info.type) {
- continue;
- }
- if (0 == strncmp(direntry->name, "log.", 4))
- {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl,
- "Deleting log file: (%s)\n", filename1);
- unlink(filename1);
- }
- rc = CL5_SUCCESS;
- }
- PR_CloseDir(dirhandle);
- }
- else if (PR_FILE_NOT_FOUND_ERROR != PR_GetError())
- {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl,
- "_cl5RemoveLogs:: PR_OpenDir(%s) failed (%d): %s\n",
- s_cl5Desc.dbDir, PR_GetError(),slapd_pr_strerror(PR_GetError()));
- }
- return rc;
-}
-#endif /* NEED_CL5_REMOVE_LOGS */
-
-static int _cl5AppInit (PRBool *didRecovery)
-{
- int rc;
- unsigned int flags = DB_CREATE | DB_INIT_MPOOL | DB_THREAD;
- DB_ENV *dbEnv;
- if ((rc = db_env_create(&dbEnv, 0)) != 0)
- dbEnv = NULL;
-
- if (dbEnv == NULL)
- {
- char *errstr = db_strerror(rc);
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "_cl5AppInit: failed to allocate db environment; db error - %d (%s)\n",
- rc, errstr ? errstr : "unknown");
- return CL5_MEMORY_ERROR;
- }
-
- _cl5InitDBEnv (dbEnv);
-
- if (didRecovery)
- *didRecovery = PR_FALSE;
-
- /* decide how two open based on the mode in which db is open */
- switch (s_cl5Desc.dbOpenMode)
- {
- case CL5_OPEN_NORMAL:
- flags |= DB_INIT_LOCK | DB_INIT_TXN | DB_INIT_LOG;
- /* check if need to initiate recovery */
- rc = _cl5CheckGuardian ();
- if (rc != CL5_SUCCESS)
- {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl,
- "_cl5AppInit: recovering changelog after disorderly shutdown\n");
- flags |= DB_RECOVER;
- }
- break;
-
- case CL5_OPEN_RESTORE:
- flags |= DB_INIT_LOCK | DB_INIT_TXN | DB_INIT_LOG;
- break;
-
- case CL5_OPEN_CLEAN_RECOVER:
- flags |= DB_INIT_LOCK | DB_INIT_TXN | DB_INIT_LOG | DB_RECOVER;
- break;
-
- case CL5_OPEN_RESTORE_RECOVER:
- flags |= DB_INIT_LOCK | DB_INIT_TXN | DB_INIT_LOG | DB_RECOVER_FATAL;
- break;
-
- case CL5_OPEN_LDIF2CL:
- /* ONREPL - don't think we need any extra flags here */
- break;
- default:
- /* fixme? CL5_OPEN_NONE */
- break;
- }
-
- if (!s_cl5Desc.dbConfig.durableTrans)
- {
-#if 1000*DB_VERSION_MAJOR + 100*DB_VERSION_MINOR >= 3200
- dbEnv->set_flags(dbEnv, DB_TXN_NOSYNC, 1);
-#else
- flags |= DB_TXN_NOSYNC;
-#endif
- }
-
- dbEnv->set_errcall(dbEnv, dblayer_log_print);
-
- /* do recovery if necessary */
- if ((flags & DB_RECOVER) || (flags & DB_RECOVER_FATAL))
- {
- if (CL5_OPEN_CLEAN_RECOVER == s_cl5Desc.dbOpenMode)
- {
- _cl5RemoveEnv();
- }
-
- rc = _cl5Recover (flags, dbEnv);
- if (rc != CL5_SUCCESS)
- {
- char *errstr = db_strerror(rc);
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl,
- "_cl5AppInit: failed to recover changelog; db error - %d %s\n",
- rc, errstr ? errstr : "unknown");
-
- slapi_ch_free ((void **)&dbEnv);
-
- return rc;
- }
-
- if (didRecovery)
- *didRecovery = PR_TRUE;
- flags &= ~(DB_RECOVER | DB_RECOVER_FATAL);
- /* Need to reset the env */
- /* Does this leak the dbEnv? */
- if ((rc = db_env_create(&dbEnv, 0)) != 0)
- dbEnv = NULL;
-
- if (dbEnv == NULL)
- {
- char *errstr = db_strerror(rc);
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "_cl5AppInit: failed to allocate db environment after recovery; "
- "db error - %d %s\n", rc, errstr ? errstr : "unknown");
- return CL5_MEMORY_ERROR;
}
- _cl5InitDBEnv (dbEnv);
+ be = slapi_get_next_backend(cookie);
}
+ slapi_ch_free((void **)&cookie);
- rc = dbEnv->open(dbEnv, s_cl5Desc.dbDir, flags,
- s_cl5Desc.dbConfig.fileMode);
- if (rc == 0)
+ if (rc == 0 && dbEnv && pagesize)
{
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl,
+ "_cl5AppInit: fetched backend dbEnv (%p)\n", dbEnv);
s_cl5Desc.dbEnv = dbEnv;
- s_cl5Desc.dbEnvOpenFlags = flags;
+ s_cl5Desc.dbConfig.pageSize = pagesize;
return CL5_SUCCESS;
}
else
{
- char *errstr = db_strerror(rc);
- char flagstr[20];
-
- flagstr[0] = 0;
- /* EINVAL return means bad flags - let's see what the flags are */
- if (rc == EINVAL)
- {
- sprintf(flagstr, "%u", flags);
- }
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "_cl5AppInit: db environment open failed; db error - %d %s %s\n",
- rc, errstr ? errstr : "unknown", flagstr);
- slapi_ch_free ((void **)&dbEnv);
+ "_cl5AppInit: failed to fetch backend dbenv (%p) and/or "
+ "index page size (%ld)\n", dbEnv, pagesize);
return CL5_DB_ERROR;
}
}
@@ -2462,7 +1836,7 @@ static int _cl5DBOpen ()
PRBool dbFile;
PRDir *dir;
PRDirEntry *entry = NULL;
- int rc;
+ int rc = -1; /* initialize to failure */
Object *replica;
int count = 0;
@@ -2765,43 +2139,16 @@ cl5DBData2Entry (const char *data, PRUint32 len, CL5Entry *entry)
/* thread management functions */
static int _cl5DispatchDBThreads ()
{
- if (NULL == PR_CreateThread (PR_USER_THREAD, (VFP)(void *)_cl5DeadlockMain,
- NULL, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
- PR_UNJOINABLE_THREAD, DEFAULT_THREAD_STACKSIZE))
- {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl,
- "_cl5DispatchDBThreads: failed to create deadlock thread; "
- "NSPR error - %d\n", PR_GetError ());
- return CL5_SYSTEM_ERROR;
- }
-
- if (NULL == PR_CreateThread (PR_USER_THREAD, (VFP)(void *)_cl5CheckpointMain,
- NULL, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
- PR_UNJOINABLE_THREAD, DEFAULT_THREAD_STACKSIZE))
- {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl,
- "_cl5DispatchDBThreads: failed to create checkpoint thread; "
- "NSPR error - %d\n", PR_GetError ());
- return CL5_SYSTEM_ERROR;
- }
-
- if (NULL == PR_CreateThread (PR_USER_THREAD, (VFP)(void *)_cl5TrickleMain,
- NULL, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
- PR_UNJOINABLE_THREAD, DEFAULT_THREAD_STACKSIZE) )
- {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl,
- "_cl5DispatchDBThreads: failed to create trickle thread; "
- "NSPR error - %d\n", PR_GetError ());
- return CL5_SYSTEM_ERROR;
- }
+ PRThread *pth = NULL;
- if (NULL == PR_CreateThread (PR_USER_THREAD, (VFP)(void*)_cl5TrimMain,
- NULL, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
- PR_UNJOINABLE_THREAD, DEFAULT_THREAD_STACKSIZE) )
+ pth = PR_CreateThread(PR_USER_THREAD, (VFP)(void*)_cl5TrimMain,
+ NULL, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+ PR_UNJOINABLE_THREAD, DEFAULT_THREAD_STACKSIZE);
+ if (NULL == pth)
{
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl,
- "_cl5DispatchDBThreads: failed to create trimming thread; "
- "NSPR error - %d\n", PR_GetError ());
+ "_cl5DispatchDBThreads: failed to create trimming "
+ "thread; NSPR error - %d\n", PR_GetError ());
return CL5_SYSTEM_ERROR;
}
@@ -3195,150 +2542,6 @@ static int _cl5WriteBervals (struct berval **bv, char** buff, unsigned int *size
return CL5_SUCCESS;
}
-static int _cl5DeadlockMain (void *param)
-{
- PRIntervalTime interval;
- int rc;
-
- PR_AtomicIncrement (&s_cl5Desc.threadCount);
- interval = PR_MillisecondsToInterval(100);
- while (s_cl5Desc.dbState != CL5_STATE_CLOSING)
- {
- int aborted;
- if ((rc = LOCK_DETECT(s_cl5Desc.dbEnv, 0, DB_LOCK_YOUNGEST, &aborted)) != 0)
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "_cl5DeadlockMain: lock_detect failed (%d transaction%s aborted); db error - %d %s\n",
- aborted, (aborted == 1)? "":"s", rc, db_strerror(rc));
- }
- else if (aborted)
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "_cl5DeadlockMain: lock_detect succeeded, but %d transaction%s ha%s been aborted\n",
- aborted, (aborted == 1)? "":"s", (aborted == 1)? "s":"ve");
- }
-
- DS_Sleep(interval);
- }
-
- PR_AtomicDecrement (&s_cl5Desc.threadCount);
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl, "_cl5DeadlockMain: exiting\n");
- return 0;
-}
-
-static int _cl5CheckpointMain (void *param)
-{
- time_t lastCheckpointCompletion = 0;
- PRIntervalTime interval;
- int rc = -1;
-
- PR_AtomicIncrement (&s_cl5Desc.threadCount);
-
- interval = PR_MillisecondsToInterval(1000);
- lastCheckpointCompletion = current_time();
-
- while (s_cl5Desc.dbState != CL5_STATE_CLOSING)
- {
- /* Check to see if the checkpoint interval has elapsed */
- if (current_time() - lastCheckpointCompletion > s_cl5Desc.dbConfig.checkpointInterval)
- {
- rc = TXN_CHECKPOINT(s_cl5Desc.dbEnv, 0, 0, 0);
- if (rc == 0)
- {
- lastCheckpointCompletion = current_time();
- }
-#if 1000*DB_VERSION_MAJOR + 100*DB_VERSION_MINOR < 4100
- else if (rc != DB_INCOMPLETE) /* real error happened */
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "_cl5CheckpointMain: checkpoint failed, db error - %d %s\n",
- rc, db_strerror(rc));
- }
-#endif
-
- /* According to dboreham, we are doing checkpoint twice
- to reduce the number of transaction log files which need
- to be retained at any time. */
- rc = TXN_CHECKPOINT(s_cl5Desc.dbEnv, 0, 0, 0);
- if (rc == 0)
- {
- lastCheckpointCompletion = current_time();
- }
-#if 1000*DB_VERSION_MAJOR + 100*DB_VERSION_MINOR < 4100
- else if (rc != DB_INCOMPLETE) /* real error happened */
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "_cl5CheckpointMain: checkpoint failed, db error - %d %s\n",
- rc, db_strerror(rc));
- }
-#endif
-
- /* check if we should truncate logs */
- if (s_cl5Desc.dbConfig.circularLogging)
- {
- char **list = NULL;
- /* find out which log files don't contain active txns */
- /* DB_ARCH_REMOVE: Remove log files that are no longer needed;
- * no filenames are returned. */
- int rc = LOG_ARCHIVE(s_cl5Desc.dbEnv, &list,
- DB_ARCH_REMOVE, (void *)slapi_ch_malloc);
- if (rc)
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "_cl5CheckpointMain: log archive failed, "
- "db error - %d %s\n", rc, db_strerror(rc));
- }
- slapi_ch_free((void **)&list); /* just in case */
- }
- else
- {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl,
- "_cl5CheckpointMain: %s is off; "
- "transaction logs won't be removed.\n",
- CONFIG_CHANGELOG_DB_CIRCULAR_LOGGING);
- }
- }
-
- /* sleep for a while */
- /* why aren't we sleeping exactly the right amount of time ? */
- /* answer---because the interval might be changed after the server starts up */
- DS_Sleep(interval);
- }
- /* Check point and archive before shutting down */
- rc = TXN_CHECKPOINT(s_cl5Desc.dbEnv, 0, 0, 0);
-
- PR_AtomicDecrement (&s_cl5Desc.threadCount);
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl, "_cl5CheckpointMain: exiting\n");
- return 0;
-}
-
-static int _cl5TrickleMain (void *param)
-{
- PRIntervalTime interval;
- int pages_written;
- int rc;
-
- PR_AtomicIncrement (&s_cl5Desc.threadCount);
- interval = PR_MillisecondsToInterval(1000);
- while (s_cl5Desc.dbState != CL5_STATE_CLOSING)
- {
- if ((rc = MEMP_TRICKLE(s_cl5Desc.dbEnv,
- s_cl5Desc.dbConfig.tricklePercentage, &pages_written)) != 0)
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "_cl5TrickleMain: memp_trickle failed; db error - %d %s\n",
- rc, db_strerror(rc));
- }
-
- DS_Sleep(interval);
- }
-
- PR_AtomicDecrement (&s_cl5Desc.threadCount);
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl, "_cl5TrickleMain: exiting\n");
-
- return 0;
-}
-
/* upgrade from db33 to db41
* 1. Run recovery on the database environment using the DB_ENV->open method
* 2. Remove any Berkeley DB environment using the DB_ENV->remove method
@@ -3422,9 +2625,6 @@ static int _cl5Upgrade3_4(char *fromVersion, char *toVersion)
}
/* update the version file */
_cl5WriteDBVersion ();
-
- /* update the guardian file */
- _cl5WriteGuardian ();
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
"Upgrading from %s to %s is successfully done (%s)\n",
fromVersion, toVersion, s_cl5Desc.dbDir);
@@ -3433,12 +2633,6 @@ out:
{
PR_CloseDir(dir);
}
- if (s_cl5Desc.dbEnv)
- {
- DB_ENV *dbEnv = s_cl5Desc.dbEnv;
- dbEnv->close(dbEnv, 0);
- s_cl5Desc.dbEnv = NULL;
- }
return rc;
}
@@ -3466,19 +2660,10 @@ static int _cl5Upgrade4_4(char *fromVersion, char *toVersion)
/* update the version file */
_cl5WriteDBVersion ();
-
- /* update the guardian file */
- _cl5WriteGuardian ();
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
"Upgrading from %s to %s is successfully done (%s)\n",
fromVersion, toVersion, s_cl5Desc.dbDir);
- if (s_cl5Desc.dbEnv)
- {
- DB_ENV *dbEnv = s_cl5Desc.dbEnv;
- dbEnv->close(dbEnv, 0);
- s_cl5Desc.dbEnv = NULL;
- }
return rc;
}
@@ -3492,9 +2677,6 @@ static int _cl5CheckDBVersion ()
{
/* this is new changelog - write DB version and guardian file */
rc = _cl5WriteDBVersion ();
- if (rc == CL5_SUCCESS) {
- rc = _cl5WriteGuardian();
- }
}
else
{
@@ -3683,161 +2865,6 @@ static int _cl5WriteDBVersion ()
return CL5_SUCCESS;
}
-/* for now guardian file is just like dbversion file */
-static int _cl5CheckGuardian ()
-{
- char plVersion [VERSION_SIZE + 1];
- char dbVersion [VERSION_SIZE + 1];
- int rc;
-
- /* new changelog - no guardian file */
- if (!cl5Exist(s_cl5Desc.dbDir))
- {
- return CL5_SUCCESS;
- }
- else
- {
- PR_snprintf (plVersion, VERSION_SIZE, "%s/%d.%d/%s\n",
- BDB_IMPL, DB_VERSION_MAJOR, DB_VERSION_MINOR, BDB_REPLPLUGIN);
- dbVersion[0] = '\0';
- rc = _cl5ReadGuardian (dbVersion);
-
- if (rc != CL5_SUCCESS || strcasecmp (plVersion, dbVersion) != 0)
- {
- PR_snprintf (plVersion, VERSION_SIZE, "%s/%s/%s",
- CL5_TYPE, REPL_PLUGIN_NAME, CHANGELOG_DB_VERSION);
- if (strcasecmp (plVersion, dbVersion) != 0)
- {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl,
- "_cl5CheckGuardian: found old style of guardian file: %s\n",
- dbVersion);
- }
- else
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "_cl5CheckGuardian: missing or invalid guardian file\n");
- return (CL5_BAD_FORMAT);
- }
- }
-
- /* remove guardian file */
- rc = _cl5RemoveGuardian ();
- if (rc != CL5_SUCCESS)
- {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl,
- "_cl5CheckGuardian: failed to remove guardian file\n");
- }
- }
-
- return rc;
-}
-
-static int _cl5WriteGuardian ()
-{
- int rc;
- PRFileDesc *file;
- char fName [MAXPATHLEN + 1];
- char version [VERSION_SIZE];
- PRInt32 len, size;
-
- PR_snprintf (fName, MAXPATHLEN, "%s/%s", s_cl5Desc.dbDir, GUARDIAN_FILE);
-
- file = PR_Open (fName, PR_WRONLY | PR_CREATE_FILE, s_cl5Desc.dbConfig.fileMode);
- if (file == NULL)
- {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl,
- "_cl5WriteGuardian: failed to open guardian file; NSPR error - %d\n",
- PR_GetError());
- return CL5_SYSTEM_ERROR;
- }
-
- PR_snprintf (version, VERSION_SIZE, "%s/%d.%d/%s\n",
- BDB_IMPL, DB_VERSION_MAJOR, DB_VERSION_MINOR, BDB_REPLPLUGIN);
-
- len = strlen (version);
- size = slapi_write_buffer (file, version, len);
- if (size != len)
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "_cl5WriteGuardian: failed to write guardian file; NSPR error - %d\n",
- PR_GetError());
- PR_Close (file);
- return CL5_SYSTEM_ERROR;
- }
-
- rc = PR_Close (file);
- if (rc != PR_SUCCESS)
- {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl,
- "_cl5WriteGuardian: failed to close guardian file; NSPR error - %d\n",
- PR_GetError());
- return CL5_SYSTEM_ERROR;
- }
-
- return CL5_SUCCESS;
-}
-
-static int _cl5ReadGuardian (char *buff)
-{
- int rc;
- PRFileDesc *file;
- char fName [MAXPATHLEN + 1];
- PRInt32 size;
-
- PR_snprintf (fName, MAXPATHLEN, "%s/%s", s_cl5Desc.dbDir, GUARDIAN_FILE);
-
- file = PR_Open (fName, PR_RDONLY, 0);
- if (file == NULL)
- {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl,
- "_cl5ReadGuardian: failed to open guardian file; NSPR error - %d\n",
- PR_GetError());
- return CL5_SYSTEM_ERROR;
- }
-
- size = slapi_read_buffer (file, buff, VERSION_SIZE);
- if (size <= 0)
- {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl,
- "_cl5ReadGuardian: failed to read guardian file; NSPR error - %d\n",
- PR_GetError());
- PR_Close (file);
- return CL5_SYSTEM_ERROR;
- }
-
- buff [size-1] = '\0';
-
- rc = PR_Close (file);
- if (rc != PR_SUCCESS)
- {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl,
- "_cl5ReadGuardian: failed to close guardian file; NSPR error - %d\n",
- PR_GetError());
- return CL5_SYSTEM_ERROR;
- }
-
- return CL5_SUCCESS;
-}
-
-static int _cl5RemoveGuardian ()
-{
- char fName [MAXPATHLEN + 1];
- int rc;
-
- PR_snprintf (fName, MAXPATHLEN, "%s/%s", s_cl5Desc.dbDir, GUARDIAN_FILE);
-
- rc = PR_Delete (fName);
- if (rc != PR_SUCCESS)
- {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl,
- "_cl5RemoveGuardian: failed to remove guardian file; NSPR error - %d\n",
- PR_GetError());
- return CL5_SYSTEM_ERROR;
- }
-
- return CL5_SUCCESS;
-}
-
/* must be called under the state lock */
static void _cl5Close ()
{
@@ -3866,27 +2893,6 @@ static void _cl5Close ()
/* cleanup trimming */
_cl5TrimCleanup ();
- /* There should be no more open databases after _cl5DBClose, so it is now
- safe to close the dbEnv */
- if (s_cl5Desc.dbEnv)
- {
- DB_ENV *dbEnv = s_cl5Desc.dbEnv;
- int rc = dbEnv->close(dbEnv, 0);
- s_cl5Desc.dbEnv = NULL;
- if (rc) {
- slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "_cl5Close: error closing DB environment: %d (%s)\n",
- rc, db_strerror(rc));
- }
- }
-
- /* record successful close by writing guardian file;
- we do it in all case accept incomplete open due to an error */
- if (s_cl5Desc.dbState == CL5_STATE_CLOSING || s_cl5Desc.dbOpenMode != CL5_OPEN_NORMAL)
- {
- _cl5WriteGuardian ();
- }
-
/* remove changelog if requested */
if (s_cl5Desc.dbRmOnClose)
{
@@ -3932,15 +2938,10 @@ static void _cl5DBClose ()
static int
_cl5IsDbFile(const char *fname)
{
- char *ptr = NULL;
if (!fname || !*fname) {
return 0;
}
- if (!strcmp(fname, GUARDIAN_FILE)) {
- return 1;
- }
-
if (!strcmp(fname, VERSION_FILE)) {
return 1;
}
@@ -3949,15 +2950,6 @@ _cl5IsDbFile(const char *fname)
return 1;
}
- if (_cl5IsLogFile(fname)) {
- return 1;
- }
-
- ptr = strstr(fname, "__db.");
- if (ptr == fname) { /* begins with __db. */
- return 1;
- }
-
return 0; /* not a filename we recognize as being associated with the db */
}
@@ -4039,149 +3031,18 @@ static int _cl5Delete (const char *clDir, int rmDir)
static void _cl5SetDefaultDBConfig ()
{
- s_cl5Desc.dbConfig.cacheSize = CL5_DEFAULT_CONFIG_DB_DBCACHESIZE;
- s_cl5Desc.dbConfig.durableTrans = CL5_DEFAULT_CONFIG_DB_DURABLE_TRANSACTIONS;
- s_cl5Desc.dbConfig.checkpointInterval = CL5_DEFAULT_CONFIG_DB_CHECKPOINT_INTERVAL;
- s_cl5Desc.dbConfig.circularLogging = CL5_DEFAULT_CONFIG_DB_CIRCULAR_LOGGING;
- s_cl5Desc.dbConfig.pageSize = CL5_DEFAULT_CONFIG_DB_PAGE_SIZE;
- s_cl5Desc.dbConfig.logfileSize = CL5_DEFAULT_CONFIG_DB_LOGFILE_SIZE;
- s_cl5Desc.dbConfig.maxTxnSize = CL5_DEFAULT_CONFIG_DB_TXN_MAX;
- s_cl5Desc.dbConfig.verbose = CL5_DEFAULT_CONFIG_DB_VERBOSE;
- s_cl5Desc.dbConfig.debug = CL5_DEFAULT_CONFIG_DB_DEBUG;
- s_cl5Desc.dbConfig.tricklePercentage = CL5_DEFAULT_CONFIG_DB_TRICKLE_PERCENTAGE;
- s_cl5Desc.dbConfig.spinCount = CL5_DEFAULT_CONFIG_DB_SPINCOUNT;
- s_cl5Desc.dbConfig.nb_lock_config = CL5_DEFAULT_CONFIG_NB_LOCK;
+ s_cl5Desc.dbConfig.maxConcurrentWrites= CL5_DEFAULT_CONFIG_MAX_CONCURRENT_WRITES;
s_cl5Desc.dbConfig.fileMode = FILE_CREATE_MODE;
}
static void _cl5SetDBConfig (const CL5DBConfig *config)
{
- /* through CL5DBConfig, we have access to all the LDAP configurable Changelog DB parameters */
- s_cl5Desc.dbConfig.cacheSize = config->cacheSize;
- s_cl5Desc.dbConfig.durableTrans = config->durableTrans;
- s_cl5Desc.dbConfig.checkpointInterval = config->checkpointInterval;
- s_cl5Desc.dbConfig.circularLogging = config->circularLogging;
- s_cl5Desc.dbConfig.pageSize = config->pageSize;
- s_cl5Desc.dbConfig.logfileSize = config->logfileSize;
- s_cl5Desc.dbConfig.maxTxnSize = config->maxTxnSize;
- s_cl5Desc.dbConfig.verbose = config->verbose;
- s_cl5Desc.dbConfig.debug = config->debug;
- s_cl5Desc.dbConfig.tricklePercentage = config->tricklePercentage;
- s_cl5Desc.dbConfig.spinCount = config->spinCount;
- s_cl5Desc.dbConfig.nb_lock_config = config->nb_lock_config;
- s_cl5Desc.dbConfig.maxConcurrentWrites = config->maxConcurrentWrites;
-
- if (config->spinCount != 0)
- {
- DB_ENV_SET_TAS_SPINS(s_cl5Desc.dbEnv, config->spinCount);
- }
-
+ /* s_cl5Desc.dbConfig.pageSize is retrieved from backend */
/* Some other configuration parameters are hardcoded... */
+ s_cl5Desc.dbConfig.maxConcurrentWrites = config->maxConcurrentWrites;
s_cl5Desc.dbConfig.fileMode = FILE_CREATE_MODE;
}
-/*
- * a wrapper for slapi_ch_free; it's declared to set slapi_ch_free in BDB
- * dbEnv->set_alloc(dbEnv, (void *)slapi_ch_malloc, (void *)slapi_ch_realloc, _cl5_api_free);
- *
- */
-void _cl5_api_free(void *ptr)
-{
- slapi_ch_free(&ptr);
-}
-
-#define ONEG 1073741824 /* one giga bytes */
-static void _cl5InitDBEnv(DB_ENV *dbEnv)
-{
- dbEnv->set_errpfx(dbEnv, "ns-slapd");
- dbEnv->set_lg_max(dbEnv, s_cl5Desc.dbConfig.logfileSize);
- dbEnv->set_tx_max(dbEnv, s_cl5Desc.dbConfig.maxTxnSize);
- dbEnv->set_cachesize(dbEnv, s_cl5Desc.dbConfig.cacheSize/ONEG,
- s_cl5Desc.dbConfig.cacheSize%ONEG,
- 0);
- /* Set default number of locks */
- dbEnv->set_lk_max_locks(dbEnv, s_cl5Desc.dbConfig.nb_lock_config);
-
- if (s_cl5Desc.dbConfig.verbose)
- {
- int on = 1;
-#if 1000*DB_VERSION_MAJOR + 100*DB_VERSION_MINOR >= 4300
- /* DB_VERB_CHKPOINT removed in 43 */
-#else
- dbEnv->set_verbose(dbEnv, DB_VERB_CHKPOINT, on);
-#endif
- dbEnv->set_verbose(dbEnv, DB_VERB_DEADLOCK, on);
- dbEnv->set_verbose(dbEnv, DB_VERB_RECOVERY, on);
- dbEnv->set_verbose(dbEnv, DB_VERB_WAITSFOR, on);
- }
- if (s_cl5Desc.dbConfig.debug)
- {
- dbEnv->set_errcall(dbEnv, _cl5DBLogPrint);
- }
-#if 1000*DB_VERSION_MAJOR + 100*DB_VERSION_MINOR >= 3300
- dbEnv->set_alloc(dbEnv, (void *)slapi_ch_malloc, (void *)slapi_ch_realloc, _cl5_api_free);
-#endif
-}
-
-#if 1000*DB_VERSION_MAJOR + 100*DB_VERSION_MINOR >= 4300
-static void _cl5DBLogPrint(const DB_ENV *dbenv, const char* prefix,
- const char *buffer)
-#else
-static void _cl5DBLogPrint(const char* prefix, char *buffer)
-#endif
-{
- /* We ignore the prefix since we know who we are anyway */
- slapi_log_error (SLAPI_LOG_FATAL, repl_plugin_name_cl, "cl5: %s\n", buffer);
-}
-
-static PRBool _cl5IsLogFile (const char *path)
-{
- int rc;
-
- /* Is the filename at least 4 characters long ? */
- if (strlen(path) < 4)
- {
- return PR_FALSE; /* Not a log file then */
- }
-
- /* Are the first 4 characters "log." ? */
- rc = strncmp(path,"log.",4);
- if (0 == rc)
- {
- /* Now, are the last 4 characters _not_ .db# ? */
- const char *piece = path + (strlen(path) - 4);
- rc = strcmp(piece, DB_EXTENSION);
- if (0 != rc)
- {
- /* Is */
- return PR_TRUE;
- }
- }
- return PR_FALSE; /* Is not */
-}
-
-static int _cl5Recover (int open_flags, DB_ENV *dbEnv)
-{
- /* If we're doing recovery, we MUST open the env single-threaded ! */
- int recover_flags = open_flags & ~DB_THREAD;
- int rc;
-
- rc = dbEnv->open(dbEnv, s_cl5Desc.dbDir, recover_flags, s_cl5Desc.dbConfig.fileMode);
-
- if (rc != 0)
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "_cl5Recover: appinit failed; db error - %d %s\n",
- rc, db_strerror(rc));
- return CL5_DB_ERROR;
- }
-
- /* Now close it so we can re-open it again... */
- dbEnv->close(dbEnv, 0);
-
- return CL5_SUCCESS;
-}
-
/* Trimming helper functions */
static int _cl5TrimInit ()
{
@@ -6325,7 +5186,9 @@ static char* _cl5Replica2FileName (Object *replica)
static char* _cl5MakeFileName (const char *replName, const char *replGen)
{
- char *fileName = slapi_ch_smprintf("%s%s%s.%s", replName, FILE_SEP, replGen, DB_EXTENSION);
+ char *fileName = slapi_ch_smprintf("%s/%s%s%s.%s",
+ s_cl5Desc.dbDir, replName,
+ FILE_SEP, replGen, DB_EXTENSION);
return fileName;
}
@@ -6569,9 +5432,7 @@ out:
* keys. To avoid the test-and-set mutexes, we could use semaphore
* to serialize the writers and avoid the high mutex contention
* that SleepyCat is unable to avoid.
- * (2) [610948] Linux master hangs for 2 hours
- * [611239] _cl5DeadlockMain: lock_detect succeeded
- * (3) DS 6.2 introduced the semaphore on all platforms (replaced
+ * (2) DS 6.2 introduced the semaphore on all platforms (replaced
* the serial lock used on Windows and Linux described above).
* The number of the concurrent writes now is configurable by
* nsslapd-changelogmaxconcurrentwrites (the server needs to
@@ -6820,40 +5681,6 @@ static int _cl5CompareDBFile (Object *el1, const void *el2)
return ((file->flags & DB_FILE_INIT) ? strcmp (file->name, name) : 1);
}
-static int _cl5CopyDBFiles (const char *srcDir, const char *destDir, Object **replicas)
-{
- char srcFile [MAXPATHLEN + 1];
- char destFile[MAXPATHLEN + 1];
- int rc;
- Object *obj;
- CL5DBFile *file;
-
- /* ONREPL currently, dbidlist is ignored because db code can't handle discrepancy between
- transaction log and present files; this should change before 5.0 ships */
- obj = objset_first_obj (s_cl5Desc.dbFiles);
- while (obj)
- {
- file = (CL5DBFile*)object_get_data (obj);
- PR_ASSERT (file);
-
- PR_snprintf(srcFile, MAXPATHLEN, "%s/%s", srcDir, file->name);
- PR_snprintf(destFile, MAXPATHLEN, "%s/%s", destDir, file->name);
- rc = copyfile(srcFile, destFile, 0, FILE_CREATE_MODE);
- if (rc != 0)
- {
- object_release (obj);
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "_cl5CopyDBFiles: failed to copy %s from %s to %s\n",
- file->name, srcDir, destDir);
- return CL5_SYSTEM_ERROR;
- }
-
- obj = objset_next_obj (s_cl5Desc.dbFiles, obj);
- }
-
- return CL5_SUCCESS;
-}
-
/*
* return 1: true (the "filename" ends with "ext")
* return 0: false
diff --git a/ldap/servers/plugins/replication/cl5_api.h b/ldap/servers/plugins/replication/cl5_api.h
index 65dec025..f300cd8a 100644
--- a/ldap/servers/plugins/replication/cl5_api.h
+++ b/ldap/servers/plugins/replication/cl5_api.h
@@ -67,23 +67,9 @@
/* changelog configuration structure */
typedef struct cl5dbconfig
{
- size_t cacheSize; /* cache size in bytes */
- PRBool durableTrans; /* flag that tells not to sync log when trans commits */
- PRInt32 checkpointInterval; /* checkpoint interval in seconds */
- PRBool circularLogging; /* flag to archive and trancate log */
size_t pageSize; /* page size in bytes */
- size_t logfileSize; /* maximum log size in bytes */
- size_t maxTxnSize; /* maximum txn table size in count*/
PRInt32 fileMode; /* file mode */
- PRBool verbose; /* Get libdb to exhale debugging info */
- PRBool debug; /* Will libdb emit debugging info into our log ? */
- PRInt32 tricklePercentage; /* guaranteed percentage of clean cache pages; 0 - 100 */
- PRInt32 spinCount; /* DB Mutex spin count */
- PRUint32 nb_lock_config; /* Number of locks in the DB lock table. New in 5.1 */
-/* The next 2 parameters are needed for configuring the changelog cache. New in 5.1 */
- PRUint32 maxChCacheEntries;
- PRUint32 maxChCacheSize;
- PRUint32 maxConcurrentWrites; /* 6.2 max number of concurrent cl writes */
+ PRUint32 maxConcurrentWrites; /* max number of concurrent cl writes */
} CL5DBConfig;
/* changelog entry format */
@@ -218,37 +204,6 @@ int cl5Close ();
*/
int cl5Delete (const char *dir);
-/* Name: cl5OpenDB
- Description: opens changelog file for specified file
- Parameters: replica - replica whose file we wish to open
- Return: CL5_SUCCESS if successful;
- CL5_BAD_STATE if the changelog is not initialized;
- CL5_BAD_DATA - if NULL id is supplied
- */
-int cl5OpenDB (Object *replica);
-
-/* Name: cl5CloseDB
- Description: closes changelog file for the specified replica
- Parameters: replica - replica whose file we wish to close
- Return: CL5_SUCCESS if successful;
- CL5_BAD_STATE if the changelog is not initialized;
- CL5_BAD_DATA - if NULL id is supplied
- CL5_NOTFOUND - nothing is known about specified database
- */
-int cl5CloseDB (Object *replica);
-
-/* Name: cl5DeleteDB
- Description: asynchronously removes changelog file for the specified replica.
- The file is physically removed when it is no longer in use.
- This function is called when a backend is removed or reloaded.
- Parameters: replica - replica whose file we wish to delete
- Return: CL5_SUCCESS if successful;
- CL5_BAD_STATE if the changelog is not initialized;
- CL5_BAD_DATA - if NULL id is supplied
- CL5_NOTFOUND - nothing is known about specified database
- */
-int cl5DeleteDB (Object *replica);
-
/* Name: cl5DeleteDBSync
Description: The same as cl5DeleteDB except the function does not return
until the file is removed.
@@ -269,36 +224,6 @@ int cl5DeleteDBSync (Object *replica);
*/
int cl5GetUpperBoundRUV (Replica *r, RUV **ruv);
-/* Name: cl5Backup
- Description: makes a backup of the changelog including *.db2,
- log files, and dbversion. Can be called with the changelog in either open or
- closed state.
- Parameters: bkDir - directory to which the data is backed up;
- created if it does not exist
- replicas - optional list of replicas whose changes should be backed up;
- if the list is NULL, entire changelog is backed up.
- Return: CL5_SUCCESS if function is successful;
- CL5_BAD_DATA if invalid directory is passed;
- CL5_BAD_STATE if changelog has not been initialized;
- CL5_DB_ERROR if db call fails;
- CL5_SYSTEM_ERROR if NSPR call or file copy failes.
- */
-int cl5Backup (const char *bkDir, Object **replicas);
-
-/* Name: cl5Restore
- Description: restores changelog from the backed up copy. Changelog must be ibnitalized and closed.
- Parameters: clDir - changelog dir
- bkDir - directory that contains the backup
- replicas - optional list of replicas whose changes should be recovered;
- if the list is NULL, entire changelog is recovered.
- Return: CL5_SUCCESS if function is successfull;
- CL5_BAD_DATA if invalid parameter is passed;
- CL5_BAD_STATE if changelog is open or not initialized;
- CL5_DB_ERROR if db call fails;
- CL5_SYSTEM_ERROR if NSPR call of file copy fails
- */
-int cl5Restore (const char *clDir, const char *bkDir, Object **replicas);
-
/* Name: cl5ExportLDIF
Description: dumps changelog to an LDIF file; changelog can be open or closed.
Parameters: clDir - changelog dir
diff --git a/ldap/servers/plugins/replication/cl5_clcache.c b/ldap/servers/plugins/replication/cl5_clcache.c
index 31947d32..af2b7fea 100644
--- a/ldap/servers/plugins/replication/cl5_clcache.c
+++ b/ldap/servers/plugins/replication/cl5_clcache.c
@@ -181,6 +181,9 @@ clcache_init ( DB_ENV **dbenv )
if (_pool) {
return 0; /* already initialized */
}
+ if (NULL == dbenv) {
+ return -1;
+ }
_pool = (struct clc_pool*) slapi_ch_calloc ( 1, sizeof ( struct clc_pool ));
_pool->pl_dbenv = dbenv;
_pool->pl_buffer_cnt_min = DEFAULT_CLC_BUFFER_COUNT_MIN;
@@ -195,20 +198,18 @@ clcache_init ( DB_ENV **dbenv )
* is read or updated.
*/
void
-clcache_set_config ( CL5DBConfig *config )
+clcache_set_config ()
{
- if ( config == NULL ) return;
-
PR_RWLock_Wlock ( _pool->pl_lock );
- _pool->pl_buffer_cnt_max = config->maxChCacheEntries;
+ _pool->pl_buffer_cnt_max = CL5_DEFAULT_CONFIG_CACHESIZE;
/*
* According to http://www.sleepycat.com/docs/api_c/dbc_get.html,
* data buffer should be a multiple of 1024 bytes in size
* for DB_MULTIPLE_KEY operation.
*/
- _pool->pl_buffer_default_pages = config->maxChCacheSize / DEFAULT_CLC_BUFFER_PAGE_SIZE + 1;
+ _pool->pl_buffer_default_pages = CL5_DEFAULT_CONFIG_CACHEMEMSIZE / DEFAULT_CLC_BUFFER_PAGE_SIZE + 1;
_pool->pl_buffer_default_pages = DEFAULT_CLC_BUFFER_PAGE_COUNT;
if ( _pool->pl_buffer_default_pages <= 0 ) {
_pool->pl_buffer_default_pages = DEFAULT_CLC_BUFFER_PAGE_COUNT;
diff --git a/ldap/servers/plugins/replication/cl5_clcache.h b/ldap/servers/plugins/replication/cl5_clcache.h
index 8c9837e9..c096d55a 100644
--- a/ldap/servers/plugins/replication/cl5_clcache.h
+++ b/ldap/servers/plugins/replication/cl5_clcache.h
@@ -50,7 +50,7 @@
typedef struct clc_buffer CLC_Buffer;
int clcache_init ( DB_ENV **dbenv );
-void clcache_set_config ( CL5DBConfig * config );
+void clcache_set_config ();
int clcache_get_buffer ( CLC_Buffer **buf, DB *db, ReplicaId consumer_rid, const RUV *consumer_ruv, const RUV *local_ruv );
int clcache_load_buffer ( CLC_Buffer *buf, CSN *startCSN, int flag );
void clcache_return_buffer ( CLC_Buffer **buf );
diff --git a/ldap/servers/plugins/replication/cl5_config.c b/ldap/servers/plugins/replication/cl5_config.c
index adbe2d01..2e66917f 100644
--- a/ldap/servers/plugins/replication/cl5_config.c
+++ b/ldap/servers/plugins/replication/cl5_config.c
@@ -329,8 +329,6 @@ changelog5_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr
config.maxEntries = CL5_NUM_IGNORE;
slapi_ch_free_string(&config.maxAge);
config.maxAge = slapi_ch_strdup(CL5_STR_IGNORE);
- config.dbconfig.maxChCacheEntries = 0;
- config.dbconfig.maxChCacheSize = (PRUint32)CL5_NUM_IGNORE;
slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
for (i = 0; mods[i] != NULL; i++)
@@ -392,28 +390,6 @@ changelog5_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr
slapi_ch_free_string(&config.maxAge);
config.maxAge = slapi_ch_strdup(config_attr_value);
}
- else if ( strcasecmp ( config_attr, CONFIG_CHANGELOG_CACHESIZE ) == 0 )
- { /* The Changelog Cache Size parameters can be modified online without a need for restart */
- if (config_attr_value && config_attr_value[0] != '\0')
- {
- config.dbconfig.maxChCacheEntries = atoi (config_attr_value);
- }
- else
- {
- config.dbconfig.maxChCacheEntries = 0;
- }
- }
- else if ( strcasecmp ( config_attr, CONFIG_CHANGELOG_CACHEMEMSIZE ) == 0 )
- { /* The Changelog Cache Size parameters can be modified online without a need for restart */
- if (config_attr_value && config_attr_value[0] != '\0')
- {
- config.dbconfig.maxChCacheSize = atoi (config_attr_value);
- }
- else
- {
- config.dbconfig.maxChCacheSize = 0;
- }
- }
else
{
*returncode = LDAP_UNWILLING_TO_PERFORM;
@@ -436,11 +412,6 @@ changelog5_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr
if (originalConfig->maxAge)
config.maxAge = slapi_ch_strdup(originalConfig->maxAge);
}
- if (config.dbconfig.maxChCacheEntries == 0)
- config.dbconfig.maxChCacheEntries = originalConfig->dbconfig.maxChCacheEntries;
- if (config.dbconfig.maxChCacheSize == (PRUint32)CL5_NUM_IGNORE)
- config.dbconfig.maxChCacheSize = originalConfig->dbconfig.maxChCacheSize;
-
/* attempt to change chagelog dir */
if (config.dir)
@@ -543,7 +514,8 @@ changelog5_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
"changelog5_config_modify: failed to restart changelog\n");
/* before finishing, let's try to do some error recovery */
- if (CL5_SUCCESS != cl5Open(currentDir, &config.dbconfig)) {
+ if (CL5_SUCCESS != cl5Open(currentDir, &config.dbconfig))
+ {
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
"changelog5_config_modify: failed to restore previous changelog\n");
}
@@ -574,9 +546,6 @@ changelog5_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr
}
}
- if (config.dbconfig.maxChCacheEntries != 0 || config.dbconfig.maxChCacheSize != (PRUint32)CL5_NUM_IGNORE)
- clcache_set_config(&config.dbconfig);
-
done:;
PR_RWLock_Unlock (s_configLock);
@@ -721,22 +690,9 @@ static changelog5Config * changelog5_dup_config(changelog5Config *config)
dup->maxEntries = config->maxEntries;
- /*memcpy((void *) &dup->dbconfig, (const void *) &config->dbconfig, sizeof(CL5DBConfig));*/
- dup->dbconfig.cacheSize = config->dbconfig.cacheSize;
- dup->dbconfig.durableTrans = config->dbconfig.durableTrans;
- dup->dbconfig.checkpointInterval = config->dbconfig.checkpointInterval;
- dup->dbconfig.circularLogging = config->dbconfig.circularLogging;
dup->dbconfig.pageSize = config->dbconfig.pageSize;
- dup->dbconfig.logfileSize = config->dbconfig.logfileSize;
- dup->dbconfig.maxTxnSize = config->dbconfig.maxTxnSize;
dup->dbconfig.fileMode = config->dbconfig.fileMode;
- dup->dbconfig.verbose = config->dbconfig.verbose;
- dup->dbconfig.debug = config->dbconfig.debug;
- dup->dbconfig.tricklePercentage = config->dbconfig.tricklePercentage;
- dup->dbconfig.spinCount = config->dbconfig.spinCount;
- dup->dbconfig.maxChCacheEntries = config->dbconfig.maxChCacheEntries;
- dup->dbconfig.maxChCacheSize = config->dbconfig.maxChCacheSize;
- dup->dbconfig.nb_lock_config = config->dbconfig.nb_lock_config;
+ dup->dbconfig.maxConcurrentWrites = config->dbconfig.maxConcurrentWrites;
return dup;
}
@@ -766,98 +722,6 @@ static void changelog5_extract_config(Slapi_Entry* entry, changelog5Config *conf
* Read the Changelog Internal Configuration Parameters for the Changelog DB
* (db cache size, db settings...)
*/
-
- /* Set configuration default values first... */
- config->dbconfig.cacheSize = CL5_DEFAULT_CONFIG_DB_DBCACHESIZE;
- config->dbconfig.durableTrans = CL5_DEFAULT_CONFIG_DB_DURABLE_TRANSACTIONS;
- config->dbconfig.checkpointInterval = CL5_DEFAULT_CONFIG_DB_CHECKPOINT_INTERVAL;
- config->dbconfig.circularLogging = CL5_DEFAULT_CONFIG_DB_CIRCULAR_LOGGING;
- config->dbconfig.pageSize = CL5_DEFAULT_CONFIG_DB_PAGE_SIZE;
- config->dbconfig.logfileSize = CL5_DEFAULT_CONFIG_DB_LOGFILE_SIZE;
- config->dbconfig.maxTxnSize = CL5_DEFAULT_CONFIG_DB_TXN_MAX;
- config->dbconfig.verbose = CL5_DEFAULT_CONFIG_DB_VERBOSE;
- config->dbconfig.debug = CL5_DEFAULT_CONFIG_DB_DEBUG;
- config->dbconfig.tricklePercentage = CL5_DEFAULT_CONFIG_DB_TRICKLE_PERCENTAGE;
- config->dbconfig.spinCount = CL5_DEFAULT_CONFIG_DB_SPINCOUNT;
- config->dbconfig.nb_lock_config = CL5_DEFAULT_CONFIG_NB_LOCK;
-
- /* Now read from the entry to override default values if needed */
- arg= slapi_entry_attr_get_charptr(entry, CONFIG_CHANGELOG_DB_DBCACHESIZE);
- if (arg)
- {
- size_t theSize = atoi (arg);
- if (theSize > CL5_MIN_DB_DBCACHESIZE)
- config->dbconfig.cacheSize = theSize;
- else {
- config->dbconfig.cacheSize = CL5_MIN_DB_DBCACHESIZE;
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "Warning: Changelog dbcache size too small. "
- "Increasing the Memory Size to %d bytes\n",
- CL5_MIN_DB_DBCACHESIZE);
- }
- slapi_ch_free_string(&arg);
- }
-
- arg= slapi_entry_attr_get_charptr(entry, CONFIG_CHANGELOG_DB_DURABLE_TRANSACTIONS);
- if (arg)
- {
- config->dbconfig.durableTrans = atoi (arg);
- slapi_ch_free_string(&arg);
- }
- arg= slapi_entry_attr_get_charptr(entry, CONFIG_CHANGELOG_DB_CHECKPOINT_INTERVAL);
- if (arg)
- {
- config->dbconfig.checkpointInterval = atoi (arg);
- slapi_ch_free_string(&arg);
- }
- arg= slapi_entry_attr_get_charptr(entry, CONFIG_CHANGELOG_DB_CIRCULAR_LOGGING);
- if (arg)
- {
- config->dbconfig.circularLogging = atoi (arg);
- slapi_ch_free_string(&arg);
- }
- arg= slapi_entry_attr_get_charptr(entry, CONFIG_CHANGELOG_DB_PAGE_SIZE);
- if (arg)
- {
- config->dbconfig.pageSize = atoi (arg);
- slapi_ch_free_string(&arg);
- }
- arg= slapi_entry_attr_get_charptr(entry, CONFIG_CHANGELOG_DB_LOGFILE_SIZE);
- if (arg)
- {
- config->dbconfig.logfileSize = atoi (arg);
- slapi_ch_free_string(&arg);
- }
- arg= slapi_entry_attr_get_charptr(entry, CONFIG_CHANGELOG_DB_MAXTXN_SIZE);
- if (arg)
- {
- config->dbconfig.maxTxnSize = atoi (arg);
- slapi_ch_free_string(&arg);
- }
- arg= slapi_entry_attr_get_charptr(entry, CONFIG_CHANGELOG_DB_VERBOSE);
- if (arg)
- {
- config->dbconfig.verbose = atoi (arg);
- slapi_ch_free_string(&arg);
- }
- arg= slapi_entry_attr_get_charptr(entry, CONFIG_CHANGELOG_DB_DEBUG);
- if (arg)
- {
- config->dbconfig.debug = atoi (arg);
- slapi_ch_free_string(&arg);
- }
- arg= slapi_entry_attr_get_charptr(entry, CONFIG_CHANGELOG_DB_TRICKLE_PERCENTAGE);
- if (arg)
- {
- config->dbconfig.tricklePercentage = atoi (arg);
- slapi_ch_free_string(&arg);
- }
- arg= slapi_entry_attr_get_charptr(entry, CONFIG_CHANGELOG_DB_SPINCOUNT);
- if (arg)
- {
- config->dbconfig.spinCount = atoi (arg);
- slapi_ch_free_string(&arg);
- }
arg= slapi_entry_attr_get_charptr(entry, CONFIG_CHANGELOG_MAX_CONCURRENT_WRITES);
if (arg)
{
@@ -868,45 +732,6 @@ static void changelog5_extract_config(Slapi_Entry* entry, changelog5Config *conf
{
config->dbconfig.maxConcurrentWrites = CL5_DEFAULT_CONFIG_MAX_CONCURRENT_WRITES;
}
-
- /*
- * Read the Changelog Internal Configuration Parameters for the Changelog Cache
- */
-
- /* Set configuration default values first... */
- config->dbconfig.maxChCacheEntries = CL5_DEFAULT_CONFIG_CACHESIZE;
- config->dbconfig.maxChCacheSize = CL5_DEFAULT_CONFIG_CACHEMEMSIZE;
-
- /* Now read from the entry to override default values if needed */
- arg= slapi_entry_attr_get_charptr(entry, CONFIG_CHANGELOG_CACHESIZE);
- if (arg)
- {
- config->dbconfig.maxChCacheEntries = atoi (arg);
- slapi_ch_free_string(&arg);
- }
- arg= slapi_entry_attr_get_charptr(entry, CONFIG_CHANGELOG_CACHEMEMSIZE);
- if (arg)
- {
- config->dbconfig.maxChCacheSize = atoi (arg);
- slapi_ch_free_string(&arg);
- }
- arg = slapi_entry_attr_get_charptr(entry, CONFIG_CHANGELOG_NB_LOCK);
- if (arg)
- {
- size_t theSize = atoi(arg);
- if (theSize < CL5_MIN_NB_LOCK)
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
- "Warning: Changelog %s value is too low (%ld). Set to minimal value instead (%d)\n",
- CONFIG_CHANGELOG_NB_LOCK, theSize, CL5_MIN_NB_LOCK);
- config->dbconfig.nb_lock_config = CL5_MIN_NB_LOCK;
- }
- else
- {
- config->dbconfig.nb_lock_config = theSize;
- }
- slapi_ch_free_string(&arg);
- }
}
static void replace_bslash (char *dir)
diff --git a/ldap/servers/plugins/replication/repl5_init.c b/ldap/servers/plugins/replication/repl5_init.c
index 8d4eb1c0..3ca3ab27 100644
--- a/ldap/servers/plugins/replication/repl5_init.c
+++ b/ldap/servers/plugins/replication/repl5_init.c
@@ -298,7 +298,8 @@ multimaster_bepreop_init( Slapi_PBlock *pb )
slapi_pblock_set( pb, SLAPI_PLUGIN_BE_PRE_ADD_FN, (void *) multimaster_bepreop_add ) != 0 ||
slapi_pblock_set( pb, SLAPI_PLUGIN_BE_PRE_DELETE_FN, (void *) multimaster_bepreop_delete ) != 0 ||
slapi_pblock_set( pb, SLAPI_PLUGIN_BE_PRE_MODIFY_FN, (void *) multimaster_bepreop_modify ) != 0 ||
- slapi_pblock_set( pb, SLAPI_PLUGIN_BE_PRE_MODRDN_FN, (void *) multimaster_bepreop_modrdn ) != 0 )
+ slapi_pblock_set( pb, SLAPI_PLUGIN_BE_PRE_MODRDN_FN, (void *) multimaster_bepreop_modrdn ) != 0 ||
+ slapi_pblock_set( pb, SLAPI_PLUGIN_BE_PRE_CLOSE_FN, (void *) cl5Close ) != 0 )
{
slapi_log_error( SLAPI_LOG_PLUGIN, repl_plugin_name, "multimaster_bepreop_init failed\n" );
rc= -1;
@@ -315,7 +316,8 @@ multimaster_bepostop_init( Slapi_PBlock *pb )
if( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01 ) != 0 ||
slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&multimasterbepostopdesc ) != 0 ||
slapi_pblock_set( pb, SLAPI_PLUGIN_BE_POST_MODRDN_FN, (void *) multimaster_bepostop_modrdn ) != 0 ||
- slapi_pblock_set( pb, SLAPI_PLUGIN_BE_POST_DELETE_FN, (void *) multimaster_bepostop_delete ) != 0 )
+ slapi_pblock_set( pb, SLAPI_PLUGIN_BE_POST_DELETE_FN, (void *) multimaster_bepostop_delete ) != 0 ||
+ slapi_pblock_set( pb, SLAPI_PLUGIN_BE_POST_OPEN_FN, (void *) changelog5_init ) != 0 )
{
slapi_log_error( SLAPI_LOG_PLUGIN, repl_plugin_name, "multimaster_bepostop_init failed\n" );
rc= -1;
diff --git a/ldap/servers/plugins/replication/repl5_plugins.c b/ldap/servers/plugins/replication/repl5_plugins.c
index a26be9ef..226e91d8 100644
--- a/ldap/servers/plugins/replication/repl5_plugins.c
+++ b/ldap/servers/plugins/replication/repl5_plugins.c
@@ -1424,13 +1424,3 @@ multimaster_be_state_change (void *handle, char *be_name, int old_be_state, int
object_release (r_obj);
}
-
-#ifdef NOTUSED
-/* Keeping the function just in case */
-static void
-close_changelog_for_replica (Object *r_obj)
-{
- if (cl5GetState () == CL5_STATE_OPEN)
- cl5CloseDB (r_obj);
-}
-#endif
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
index 69a9a2c8..527c964e 100644
--- a/ldap/servers/plugins/replication/repl_extop.c
+++ b/ldap/servers/plugins/replication/repl_extop.c
@@ -1268,6 +1268,9 @@ multimaster_extop_EndNSDS50ReplicationRequest(Slapi_PBlock *pb)
response = NSDS50_REPL_REPLICA_RELEASE_SUCCEEDED;
/* Outbound replication agreements need to all be restarted now */
/* XXXGGOOD RESTART REEPL AGREEMENTS */
+ } else {
+ /* Unless bail out, we return uninitialized response */
+ goto free_and_return;
}
}
diff --git a/ldap/servers/slapd/back-ldbm/archive.c b/ldap/servers/slapd/back-ldbm/archive.c
index edaa5edf..545a4b0c 100644
--- a/ldap/servers/slapd/back-ldbm/archive.c
+++ b/ldap/servers/slapd/back-ldbm/archive.c
@@ -151,7 +151,7 @@ int ldbm_back_archive2ldbm( Slapi_PBlock *pb )
}
}
- /* now take down ALL BACKENDS */
+ /* now take down ALL BACKENDS and changelog */
for (inst_obj = objset_first_obj(li->li_instance_set); inst_obj;
inst_obj = objset_next_obj(li->li_instance_set, inst_obj)) {
inst = (ldbm_instance *)object_get_data(inst_obj);
@@ -167,6 +167,7 @@ int ldbm_back_archive2ldbm( Slapi_PBlock *pb )
cache_clear(&inst->inst_dncache, CACHE_TYPE_DN);
}
}
+ plugin_call_plugins (pb, SLAPI_PLUGIN_BE_PRE_CLOSE_FN);
/* now we know nobody's using any of the backend instances, so we
* can shutdown the dblayer -- this closes all instances too.
* Use DBLAYER_RESTORE_MODE to prevent loss of perfctr memory.
@@ -246,7 +247,8 @@ int ldbm_back_archive2ldbm( Slapi_PBlock *pb )
goto out;
}
}
- /* bring all backends back online */
+ /* bring all backends and changelog back online */
+ plugin_call_plugins (pb, SLAPI_PLUGIN_BE_POST_OPEN_FN);
for (inst_obj = objset_first_obj(li->li_instance_set); inst_obj;
inst_obj = objset_next_obj(li->li_instance_set, inst_obj)) {
inst = (ldbm_instance *)object_get_data(inst_obj);
@@ -316,8 +318,6 @@ int ldbm_back_ldbm2archive( Slapi_PBlock *pb )
directory = rel2abspath(rawdirectory);
if (stat(directory, &sbuf) == 0) {
- int baklen = 0;
-
if (slapd_comp_path(directory, li->li_directory) == 0) {
LDAPDebug(LDAP_DEBUG_ANY,
"db2archive: Cannot archive to the db directory.\n", 0, 0, 0);
@@ -329,9 +329,7 @@ int ldbm_back_ldbm2archive( Slapi_PBlock *pb )
goto out;
}
- baklen = strlen(directory) + 5; /* ".bak\0" */
- dir_bak = slapi_ch_malloc(baklen);
- PR_snprintf(dir_bak, baklen, "%s.bak", directory);
+ dir_bak = slapi_ch_smprintf("%s.bak", directory);
LDAPDebug(LDAP_DEBUG_ANY, "db2archive: %s exists. Renaming to %s\n",
directory, dir_bak, 0);
if (task) {
@@ -442,22 +440,33 @@ int ldbm_back_ldbm2archive( Slapi_PBlock *pb )
}
}
err:
- if (return_value != 0) {
- LDAPDebug(LDAP_DEBUG_ANY, "db2archive: Rename %s back to %s\n",
- dir_bak, directory, 0);
- if (task) {
- slapi_task_log_notice(task, "Rename %s back to %s",
- dir_bak, directory);
+ if (return_value) {
+ if (dir_bak) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "db2archive failed: renaming %s back to %s\n",
+ dir_bak, directory);
+ if (task) {
+ slapi_task_log_notice(task,
+ "db2archive failed: renaming %s back to %s",
+ dir_bak, directory);
+ }
+ } else {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "db2archive failed: removing %s\n", directory);
+ if (task) {
+ slapi_task_log_notice(task, "db2archive failed: removing %s",
+ directory);
+ }
}
ldbm_delete_dirs(directory);
- if (PR_SUCCESS != PR_Rename(dir_bak, directory)) {
+ if (dir_bak && (PR_SUCCESS != PR_Rename(dir_bak, directory))) {
PRErrorCode prerr = PR_GetError();
- LDAPDebug(LDAP_DEBUG_ANY,
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
"db2archive: Failed to rename \"%s\" to \"%s\".\n",
- dir_bak, directory, 0);
- LDAPDebug(LDAP_DEBUG_ANY,
+ dir_bak, directory);
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
- prerr, slapd_pr_strerror(prerr), 0);
+ prerr, slapd_pr_strerror(prerr));
if (task) {
slapi_task_log_notice(task,
"Failed to rename \"%s\" to \"%s\".",
diff --git a/ldap/servers/slapd/back-ldbm/back-ldbm.h b/ldap/servers/slapd/back-ldbm/back-ldbm.h
index f4a6f434..29d18458 100644
--- a/ldap/servers/slapd/back-ldbm/back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h
@@ -844,4 +844,8 @@ typedef struct _back_search_result_set
/* Initial entryusn value */
#define INITIALUSN (PRUint64)(-1)
+/* changelog backup dir name
+ * starting with '.' to reduce the risk to match an ordinary backend name */
+#define CHANGELOG_BACKUPDIR ".repl_changelog_backup"
+
#endif /* _back_ldbm_h_ */
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
index a17ba5ce..cd388c9b 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
@@ -4320,6 +4320,50 @@ static int dblayer_force_checkpoint(struct ldbminfo *li)
return ret;
}
+static int
+_dblayer_delete_aux_dir(struct ldbminfo *li, char *path)
+{
+ PRDir *dirhandle = NULL;
+ PRDirEntry *direntry = NULL;
+ char filename[MAXPATHLEN];
+ dblayer_private *priv = NULL;
+ struct dblayer_private_env *pEnv = NULL;
+ int rc = -1;
+
+ if (NULL == li || NULL == path) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "_dblayer_delete_aux_dir: Invalid LDBM info (0x%x) "
+ "or path (0x%x)\n", li, path);
+ return rc;
+ }
+ priv = (dblayer_private*)li->li_dblayer_private;
+ if (priv) {
+ pEnv = priv->dblayer_env;
+ }
+ dirhandle = PR_OpenDir(path);
+ if (!dirhandle) {
+ return 0; /* The dir does not exist. */
+ }
+ while (NULL != (direntry = PR_ReadDir(dirhandle,
+ PR_SKIP_DOT | PR_SKIP_DOT_DOT))) {
+ if (! direntry->name)
+ break;
+ PR_snprintf(filename, sizeof(filename), "%s/%s", path, direntry->name);
+ if (pEnv &&
+ strcmp(LDBM_FILENAME_SUFFIX , last_four_chars(direntry->name)) == 0)
+ {
+ rc = dblayer_db_remove_ex(pEnv, filename, 0, PR_TRUE);
+ }
+ else
+ {
+ rc = ldbm_delete_dirs(filename);
+ }
+ }
+ PR_CloseDir(dirhandle);
+ PR_RmDir(path);
+ return rc;
+}
+
/* TEL: Added startdb flag. If set (1), the DB environment will be started so
* that dblayer_db_remove_ex will be used to remove the database files instead
* of simply deleting them. That is important when doing a selective restoration
@@ -4339,7 +4383,8 @@ static int _dblayer_delete_instance_dir(ldbm_instance *inst, int startdb)
if (NULL == li)
{
- LDAPDebug(LDAP_DEBUG_ANY, "_dblayer_delete_instance_dir: NULL LDBM info\n", 0, 0, 0);
+ LDAPDebug0Args(LDAP_DEBUG_ANY,
+ "_dblayer_delete_instance_dir: NULL LDBM info\n");
rval = -1;
goto done;
}
@@ -4461,7 +4506,8 @@ int dblayer_delete_instance_dir(backend *be)
* this is used mostly for restores.
* dblayer is assumed to be closed.
*/
-int dblayer_delete_database_ex(struct ldbminfo *li, char *instance)
+static int
+dblayer_delete_database_ex(struct ldbminfo *li, char *instance, char *cldir)
{
dblayer_private *priv = NULL;
Object *inst_obj;
@@ -4504,6 +4550,17 @@ int dblayer_delete_database_ex(struct ldbminfo *li, char *instance)
}
}
+ /* changelog path is given; delete it, too. */
+ if (cldir) {
+ ret = _dblayer_delete_aux_dir(li, cldir);
+ if (ret) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "dblayer_delete_database: failed to deelete \"%s\"\n",
+ chdir);
+ return ret;
+ }
+ }
+
/* now smash everything else in the db/ dir */
dirhandle = PR_OpenDir(priv->dblayer_home_directory);
if (! dirhandle)
@@ -4567,7 +4624,7 @@ int dblayer_delete_database_ex(struct ldbminfo *li, char *instance)
*/
int dblayer_delete_database(struct ldbminfo *li)
{
- return dblayer_delete_database_ex(li, NULL);
+ return dblayer_delete_database_ex(li, NULL, NULL);
}
@@ -4830,7 +4887,6 @@ dblayer_copy_directory(struct ldbminfo *li,
char *inst_dirp = NULL;
char inst_dir[MAXPATHLEN];
char sep;
- ldbm_instance *inst;
if (!src_dir || '\0' == *src_dir)
{
@@ -4854,15 +4910,6 @@ dblayer_copy_directory(struct ldbminfo *li,
else
relative_instance_name++;
- inst = ldbm_instance_find_by_name(li, relative_instance_name);
- if (NULL == inst)
- {
- LDAPDebug(LDAP_DEBUG_ANY, "Backend instance \"%s\" does not exist; "
- "Instance path %s could be invalid.\n",
- relative_instance_name, src_dir, 0);
- return return_value;
- }
-
if (is_fullpath(src_dir))
{
new_src_dir = src_dir;
@@ -4870,6 +4917,16 @@ dblayer_copy_directory(struct ldbminfo *li,
else
{
int len;
+ ldbm_instance *inst =
+ ldbm_instance_find_by_name(li, relative_instance_name);
+ if (NULL == inst)
+ {
+ LDAPDebug(LDAP_DEBUG_ANY, "Backend instance \"%s\" does not exist; "
+ "Instance path %s could be invalid.\n",
+ relative_instance_name, src_dir, 0);
+ return return_value;
+ }
+
inst_dirp = dblayer_get_full_inst_dir(inst->inst_li, inst,
inst_dir, MAXPATHLEN);
if (!inst_dirp || !*inst_dirp)
@@ -5009,21 +5066,98 @@ out:
return return_value;
}
+/*
+ * Get changelogdir from cn=changelog5,cn=config
+ * The value does not have trailing spaces nor slashes.
+ */
+static int
+_dblayer_get_changelogdir(struct ldbminfo *li, char **changelogdir)
+{
+ Slapi_PBlock *pb = NULL;
+ Slapi_Entry **entries = NULL;
+ Slapi_Attr *attr = NULL;
+ Slapi_Value *v = NULL;
+ const char *s = NULL;
+ char *attrs[2];
+ int rc = -1;
+
+ if (NULL == li || NULL == changelogdir) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ERROR: _dblayer_get_changelogdir: Invalid arg: "
+ "li: 0x%x, changelogdir: 0x%x\n", li, changelogdir);
+ return rc;
+ }
+ *changelogdir = NULL;
+ pb = slapi_pblock_new();
+ attrs[0] = CHANGELOGDIRATTR;
+ attrs[1] = NULL;
+ slapi_search_internal_set_pb(pb, CHANGELOGENTRY,
+ LDAP_SCOPE_BASE, "cn=*", attrs, 0, NULL, NULL,
+ li->li_identity, 0);
+ slapi_search_internal_pb(pb);
+ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
+
+ if (LDAP_NO_SUCH_OBJECT == rc) {
+ /* No changelog; Most likely standalone or not a master. */
+ rc = LDAP_SUCCESS;
+ goto bail;
+ }
+ if (LDAP_SUCCESS != rc) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "ERROR: Failed to search \"%s\"\n", CHANGELOGENTRY);
+ goto bail;
+ }
+ /* rc == LDAP_SUCCESS */
+ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
+ if (NULL == entries) {
+ /* No changelog */
+ goto bail;
+ }
+ /* There should be only one entry. */
+ rc = slapi_entry_attr_find(entries[0], CHANGELOGDIRATTR, &attr);
+ if (rc || NULL == attr) {
+ /* No changelog dir */
+ rc = LDAP_SUCCESS;
+ goto bail;
+ }
+ rc = slapi_attr_first_value(attr, &v);
+ if (rc || NULL == v) {
+ /* No changelog dir */
+ rc = LDAP_SUCCESS;
+ goto bail;
+ }
+ rc = LDAP_SUCCESS;
+ s = slapi_value_get_string(v);
+ if (NULL == s) {
+ /* No changelog dir */
+ goto bail;
+ }
+ *changelogdir = slapi_ch_strdup(s);
+ /* Remove trailing spaces and '/' if any */
+ normalize_dir(*changelogdir);
+bail:
+ slapi_free_search_results_internal(pb);
+ slapi_pblock_destroy(pb);
+ return rc;
+}
/* Destination Directory is an absolute pathname */
-int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
+int
+dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
{
dblayer_private *priv = NULL;
char **listA = NULL, **listB = NULL, **listi, **listj, *prefix;
char *home_dir = NULL;
- int return_value = 0;
+ int return_value = -1;
char *pathname1;
char *pathname2;
back_txn txn;
int cnt = 1, ok = 0;
- ldbm_instance *inst;
Object *inst_obj;
+ char inst_dir[MAXPATHLEN];
+ char *inst_dirp = NULL;
+ char *changelogdir = NULL;
PR_ASSERT(NULL != li);
priv = (dblayer_private*)li->li_dblayer_private;
@@ -5031,9 +5165,9 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
home_dir = dblayer_get_home_dir(li, NULL);
if (NULL == home_dir || '\0' == *home_dir)
{
- LDAPDebug(LDAP_DEBUG_ANY,
- "Backup failed due to missing db home directory info\n", 0, 0, 0);
- return -1;
+ LDAPDebug0Args(LDAP_DEBUG_ANY,
+ "Backup: missing db home directory info\n");
+ return return_value;
}
/*
@@ -5068,15 +5202,16 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
dblayer_force_checkpoint(li);
dblayer_txn_init(li,&txn);
return_value=dblayer_txn_begin(li,NULL,&txn);
- if (0 != return_value) {
- LDAPDebug(LDAP_DEBUG_ANY,
- "Backup failed due to transaction failure\n", 0, 0, 0);
- return -1;
+ if (return_value) {
+ LDAPDebug0Args(LDAP_DEBUG_ANY,
+ "Backup: transaction error\n");
+ return return_value;
}
if ( g_get_shutdown() || c_get_shutdown() ) {
- dblayer_txn_abort(li,&txn);
- return -1;
+ LDAPDebug0Args(LDAP_DEBUG_ANY, "Backup aborted\n");
+ return_value = -1;
+ goto bail;
}
/* repeat this until the logfile sets match... */
@@ -5085,73 +5220,104 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
if (priv->dblayer_enable_transactions) {
return_value = LOG_ARCHIVE(priv->dblayer_env->dblayer_DB_ENV,
&listA, DB_ARCH_LOG, (void *)slapi_ch_malloc);
- if ((return_value != 0) || (listA == NULL)) {
- LDAPDebug(LDAP_DEBUG_ANY, "BAD: can't get list of logs\n",
- 0, 0, 0);
- dblayer_txn_abort(li,&txn);
- return return_value;
+ if (return_value || (listA == NULL)) {
+ LDAPDebug0Args(LDAP_DEBUG_ANY,
+ "Backup: log archive error\n");
+ if (task) {
+ slapi_task_log_notice(task, "Backup: log archive error\n");
+ }
+ return_value = -1;
+ goto bail;
}
} else {
ok=1;
}
if ( g_get_shutdown() || c_get_shutdown() ) {
- dblayer_txn_abort(li,&txn);
- return -1;
+ LDAPDebug0Args(LDAP_DEBUG_ANY, "Backup aborted\n");
+ return_value = -1;
+ goto bail;
}
for (inst_obj = objset_first_obj(li->li_instance_set); inst_obj;
inst_obj = objset_next_obj(li->li_instance_set, inst_obj))
{
- char inst_dir[MAXPATHLEN];
- char *inst_dirp = NULL;
- inst = (ldbm_instance *)object_get_data(inst_obj);
+ ldbm_instance *inst = (ldbm_instance *)object_get_data(inst_obj);
inst_dirp = dblayer_get_full_inst_dir(inst->inst_li, inst,
- inst_dir, MAXPATHLEN);
- if (inst_dirp && *inst_dirp)
- {
- return_value = dblayer_copy_directory(li, task, inst_dirp,
- dest_dir, 0 /* backup */, &cnt, 0, 0, 0);
- }
- else
- {
- LDAPDebug(LDAP_DEBUG_ANY,
- "ERROR: Instance dir is empty\n", 0, 0, 0);
+ inst_dir, MAXPATHLEN);
+ if ((NULL == inst_dirp) || ('\0' == *inst_dirp)) {
+ LDAPDebug0Args(LDAP_DEBUG_ANY,
+ "Backup: Instance dir is empty\n");
if (task) {
slapi_task_log_notice(task,
- "ERROR: Instance dir is empty\n");
+ "Backup: Instance dir is empty\n");
}
- slapi_ch_free((void **)&listA);
- dblayer_txn_abort(li,&txn);
- return -1;
+ return_value = -1;
+ goto bail;
}
- if (return_value != 0) {
+ return_value = dblayer_copy_directory(li, task, inst_dirp,
+ dest_dir, 0 /* backup */,
+ &cnt, 0, 0, 0);
+ if (return_value) {
LDAPDebug(LDAP_DEBUG_ANY,
- "ERROR: error copying directory (%s -> %s): err=%d\n",
- inst_dirp, dest_dir, return_value);
+ "Backup: error in copying directory "
+ "(%s -> %s): err=%d\n",
+ inst_dirp, dest_dir, return_value);
if (task) {
slapi_task_log_notice(task,
- "ERROR: error copying directory (%s -> %s): err=%d",
- inst_dirp, dest_dir, return_value);
+ "Backup: error in copying directory "
+ "(%s -> %s): err=%d\n",
+ inst_dirp, dest_dir, return_value);
}
- slapi_ch_free((void **)&listA);
- dblayer_txn_abort(li,&txn);
if (inst_dirp != inst_dir)
slapi_ch_free_string(&inst_dirp);
- return return_value;
+ goto bail;
}
if (inst_dirp != inst_dir)
slapi_ch_free_string(&inst_dirp);
}
+ /* Get changelogdir, if any */
+ _dblayer_get_changelogdir(li, &changelogdir);
+ if (changelogdir) {
+ /* dest dir for changelog: dest_dir/repl_changelog_backup */
+ char *changelog_destdir = slapi_ch_smprintf("%s/%s",
+ dest_dir, CHANGELOG_BACKUPDIR);
+ return_value = dblayer_copy_directory(li, task, changelogdir,
+ changelog_destdir,
+ 0 /* backup */,
+ &cnt, 0, 0, 0);
+ if (return_value) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "Backup: error in copying directory "
+ "(%s -> %s): err=%d\n",
+ changelogdir, changelog_destdir, return_value);
+ if (task) {
+ slapi_task_log_notice(task,
+ "Backup: error in copying directory "
+ "(%s -> %s): err=%d\n",
+ changelogdir, changelog_destdir, return_value);
+ }
+ slapi_ch_free_string(&changelog_destdir);
+ goto bail;
+ }
+ /* Copy DBVERSION */
+ pathname1 = slapi_ch_smprintf("%s/%s",
+ changelogdir, DBVERSION_FILENAME);
+ pathname2 = slapi_ch_smprintf("%s/%s",
+ changelog_destdir, DBVERSION_FILENAME);
+ return_value = dblayer_copyfile(pathname1, pathname2,
+ 0, priv->dblayer_file_mode);
+ slapi_ch_free_string(&pathname1);
+ slapi_ch_free_string(&pathname1);
+ slapi_ch_free_string(&changelog_destdir);
+ }
if (priv->dblayer_enable_transactions) {
/* now, get the list of logfiles that still exist */
return_value = LOG_ARCHIVE(priv->dblayer_env->dblayer_DB_ENV,
&listB, DB_ARCH_LOG, (void *)slapi_ch_malloc);
- if ((return_value != 0) || (listB == NULL)) {
- LDAPDebug(LDAP_DEBUG_ANY, "ERROR: can't get list of logs\n",
- 0, 0, 0);
- slapi_ch_free((void **)&listA);
- dblayer_txn_abort(li,&txn);
- return return_value;
+ if (return_value || (listB == NULL)) {
+ LDAPDebug0Args(LDAP_DEBUG_ANY,
+ "Backup: can't get list of logs\n");
+ goto bail;
}
/* compare: make sure everything in list A is still in list B */
@@ -5166,8 +5332,9 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
}
if (! found) {
ok = 0; /* missing log: start over */
- LDAPDebug(LDAP_DEBUG_ANY, "WARNING: Log %s has been swiped "
- "out from under me! (retrying)\n", *listi, 0, 0);
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "WARNING: Log %s has been swiped "
+ "out from under me! (retrying)\n", *listi);
if (task) {
slapi_task_log_notice(task,
"WARNING: Log %s has been swiped out from under me! "
@@ -5177,8 +5344,9 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
}
if ( g_get_shutdown() || c_get_shutdown() ) {
- dblayer_txn_abort(li,&txn);
- return -1;
+ LDAPDebug0Args(LDAP_DEBUG_ANY, "Backup aborted\n");
+ return_value = -1;
+ goto bail;
}
if (ok) {
@@ -5201,8 +5369,8 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
for (listptr = listB; listptr && *listptr && ok; ++listptr) {
PR_snprintf(pathname1, p1len, "%s/%s", prefix, *listptr);
PR_snprintf(pathname2, p2len, "%s/%s", dest_dir, *listptr);
- LDAPDebug(LDAP_DEBUG_ANY, "Backing up file %d (%s)\n",
- cnt, pathname2, 0);
+ LDAPDebug2Args(LDAP_DEBUG_ANY, "Backing up file %d (%s)\n",
+ cnt, pathname2);
if (task)
{
slapi_task_log_notice(task,
@@ -5213,9 +5381,9 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
return_value = dblayer_copyfile(pathname1, pathname2,
0, priv->dblayer_file_mode);
if (0 > return_value) {
- LDAPDebug(LDAP_DEBUG_ANY, "Error copying file '%s' "
- "(err=%d) -- Starting over...\n",
- pathname1, return_value, 0);
+ LDAPDebug2Args(LDAP_DEBUG_ANY, "Backup: error in "
+ "copying file '%s' (err=%d) -- Starting over...\n",
+ pathname1, return_value);
if (task) {
slapi_task_log_notice(task,
"Error copying file '%s' (err=%d) -- Starting "
@@ -5224,8 +5392,11 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
ok = 0;
}
if ( g_get_shutdown() || c_get_shutdown() ) {
- dblayer_txn_abort(li,&txn);
- return -1;
+ LDAPDebug0Args(LDAP_DEBUG_ANY, "Backup aborted\n");
+ return_value = -1;
+ slapi_ch_free((void **)&pathname1);
+ slapi_ch_free((void **)&pathname2);
+ goto bail;
}
cnt++;
}
@@ -5238,22 +5409,28 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
}
} while (!ok);
-
- if ( g_get_shutdown() || c_get_shutdown() ) {
- dblayer_txn_abort(li,&txn);
- return -1;
- }
-
/* now copy the version file */
pathname1 = slapi_ch_smprintf("%s/%s", home_dir, DBVERSION_FILENAME);
pathname2 = slapi_ch_smprintf("%s/%s", dest_dir, DBVERSION_FILENAME);
- LDAPDebug(LDAP_DEBUG_ANY, "Backing up file %d (%s)\n",
- cnt, pathname2, 0);
+ LDAPDebug2Args(LDAP_DEBUG_ANY, "Backing up file %d (%s)\n", cnt, pathname2);
if (task) {
slapi_task_log_notice(task, "Backing up file %d (%s)", cnt, pathname2);
slapi_task_log_status(task, "Backing up file %d (%s)", cnt, pathname2);
}
- return_value = dblayer_copyfile(pathname1,pathname2,0,priv->dblayer_file_mode);
+ return_value =
+ dblayer_copyfile(pathname1, pathname2, 0, priv->dblayer_file_mode);
+ if (return_value) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "Backup: error in copying version file "
+ "(%s -> %s): err=%d\n",
+ pathname1, pathname2, return_value);
+ if (task) {
+ slapi_task_log_notice(task,
+ "Backup: error in copying version file "
+ "(%s -> %s): err=%d\n",
+ pathname1, pathname2, return_value);
+ }
+ }
slapi_ch_free((void **)&pathname1);
slapi_ch_free((void **)&pathname2);
@@ -5261,8 +5438,11 @@ int dblayer_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
if (0 == return_value) /* if everything went well, backup the index conf */
return_value = dse_conf_backup(li, dest_dir);
-
- return_value = dblayer_txn_abort(li,&txn);
+bail:
+ slapi_ch_free((void **)&listA);
+ slapi_ch_free((void **)&listB);
+ dblayer_txn_abort(li,&txn);
+ slapi_ch_free_string(&changelogdir);
return return_value;
}
@@ -5560,7 +5740,7 @@ static int dblayer_fri_restore(char *home_dir, char *src_dir, dblayer_private *p
int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *bename)
{
dblayer_private *priv = NULL;
- int return_value = 0;
+ int return_value = 0;
int tmp_rval;
char filename1[MAXPATHLEN];
char filename2[MAXPATHLEN];
@@ -5576,6 +5756,10 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
char *real_src_dir = NULL;
int frirestore = 0; /* Is a an FRI/single instance restore. 0 for no, 1 for yes */
struct stat sbuf;
+ char *changelogdir = NULL;
+ char *restore_dir = NULL;
+ char *prefix = NULL;
+ int cnt = 1;
PR_ASSERT(NULL != li);
priv = (dblayer_private*)li->li_dblayer_private;
@@ -5595,8 +5779,8 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
if (NULL == home_dir || '\0' == *home_dir)
{
- LDAPDebug(LDAP_DEBUG_ANY,
- "Restore failed due to missing db home directory info\n", 0, 0, 0);
+ LDAPDebug0Args(LDAP_DEBUG_ANY,
+ "Restore: missing db home directory info\n");
return -1;
}
@@ -5605,27 +5789,27 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
/* We check on the source staging area, no point in going further if it
* isn't there */
if (stat(src_dir, &sbuf) < 0) {
- LDAPDebug(LDAP_DEBUG_ANY, "restore: backup directory %s does not "
- "exist.\n", src_dir, 0, 0);
+ LDAPDebug1Arg(LDAP_DEBUG_ANY, "Restore: backup directory %s does not "
+ "exist.\n", src_dir);
if (task) {
- slapi_task_log_notice(task,
- "Backup directory %s does not exist.\n", src_dir);
+ slapi_task_log_notice(task, "Restore: backup directory %s does not "
+ "exist.\n", src_dir);
}
return LDAP_UNWILLING_TO_PERFORM;
} else if (!S_ISDIR(sbuf.st_mode)) {
- LDAPDebug(LDAP_DEBUG_ANY, "restore: backup directory %s is not "
- "a directory.\n", src_dir, 0, 0);
+ LDAPDebug1Arg(LDAP_DEBUG_ANY, "Restore: backup directory %s is not "
+ "a directory.\n", src_dir);
if (task) {
- slapi_task_log_notice(task,
- "Backup directory %s is not a directory.\n", src_dir);
+ slapi_task_log_notice(task, "Restore: backup directory %s is not "
+ "a directory.\n", src_dir);
}
return LDAP_UNWILLING_TO_PERFORM;
}
if (!dbversion_exists(li, src_dir)) {
- LDAPDebug(LDAP_DEBUG_ANY, "restore: backup directory %s does not "
- "contain a complete backup\n", src_dir, 0, 0);
+ LDAPDebug1Arg(LDAP_DEBUG_ANY, "Restore: backup directory %s does not "
+ "contain a complete backup\n", src_dir);
if (task) {
- slapi_task_log_notice(task, "Backup directory %s does not "
+ slapi_task_log_notice(task, "Restore: backup directory %s does not "
"contain a complete backup", src_dir );
}
return LDAP_UNWILLING_TO_PERFORM;
@@ -5646,34 +5830,50 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
while ((direntry = PR_ReadDir(dirhandle, PR_SKIP_DOT | PR_SKIP_DOT_DOT))
&& direntry->name)
{
- PR_snprintf(filename1, MAXPATHLEN, "%s/%s", src_dir, direntry->name);
+ PR_snprintf(filename1, sizeof(filename1), "%s/%s",
+ src_dir, direntry->name);
if(!frirestore || strcmp(direntry->name,bename)==0)
{
tmp_rval = PR_GetFileInfo(filename1, &info);
if (tmp_rval == PR_SUCCESS && PR_FILE_DIRECTORY == info.type) {
+ /* Is it CHANGELOG_BACKUPDIR? */
+ if (0 == strcmp(CHANGELOG_BACKUPDIR, direntry->name)) {
+ /* Yes, this is a changelog backup. */
+ /* Get the changelog path */
+ _dblayer_get_changelogdir(li, &changelogdir);
+ continue;
+ }
inst = ldbm_instance_find_by_name(li, (char *)direntry->name);
if ( inst == NULL)
{
- LDAPDebug(LDAP_DEBUG_ANY,
- "ERROR: target server has no %s configured\n", direntry->name, 0, 0);
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "Restore: target server has no %s configured\n",
+ direntry->name);
if (task) {
slapi_task_log_notice(task,
- "ERROR: target server has no %s configured\n", direntry->name);
+ "Restore: target server has no %s configured\n",
+ direntry->name);
}
PR_CloseDir(dirhandle);
- return LDAP_UNWILLING_TO_PERFORM;
+ return_value = LDAP_UNWILLING_TO_PERFORM;
+ goto error_out;
}
if (slapd_comp_path(src_dir, inst->inst_parent_dir_name)
== 0) {
- LDAPDebug(LDAP_DEBUG_ANY,
- "ERROR: backup dir %s and target dir %s are identical\n", src_dir, inst->inst_parent_dir_name, 0);
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "Restore: backup dir %s and target dir %s "
+ "are identical\n",
+ src_dir, inst->inst_parent_dir_name);
if (task) {
slapi_task_log_notice(task,
- "ERROR: backup dir %s and target dir %s are identical\n", src_dir, inst->inst_parent_dir_name);
+ "Restore: backup dir %s and target dir %s "
+ "are identical\n",
+ src_dir, inst->inst_parent_dir_name);
}
PR_CloseDir(dirhandle);
- return LDAP_UNWILLING_TO_PERFORM;
+ return_value = LDAP_UNWILLING_TO_PERFORM;
+ goto error_out;
}
}
}
@@ -5682,10 +5882,10 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
}
/* We delete the existing database */
-
- return_value = dblayer_delete_database_ex(li, bename);
+ /* changelogdir is taken care only when it's not NULL. */
+ return_value = dblayer_delete_database_ex(li, bename, changelogdir);
if (return_value) {
- return return_value;
+ goto error_out;
}
if (frirestore) /*if we are restoring a single backend*/
@@ -5693,7 +5893,7 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
char *new_src_dir = NULL;
return_value = dblayer_fri_restore(home_dir,src_dir,priv,task,&new_src_dir,bename);
if (return_value) {
- return return_value;
+ goto error_out;
}
/* Now modify the src_dir to point to our recovery area and carry on as if nothing had happened... */
real_src_dir = new_src_dir;
@@ -5707,91 +5907,141 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
/* We want to treat the logfiles specially: if there's
* a log file directory configured, copy the logfiles there
* rather than to the db dirctory */
- if (0 == return_value) {
- dirhandle = PR_OpenDir(real_src_dir);
- if (NULL != dirhandle) {
- char *restore_dir;
- char *prefix = NULL;
- int cnt = 1;
-
-
- while (NULL != (direntry = PR_ReadDir(dirhandle, PR_SKIP_DOT | PR_SKIP_DOT_DOT))) {
- if (NULL == direntry->name) {
- /* NSPR doesn't behave like the docs say it should */
- break;
- }
-
-
- /* Is this entry a directory? */
- PR_snprintf(filename1, MAXPATHLEN, "%s/%s", real_src_dir, direntry->name);
- tmp_rval = PR_GetFileInfo(filename1, &info);
- if (tmp_rval == PR_SUCCESS && PR_FILE_DIRECTORY == info.type) {
- /* This is an instance directory. It contains the *.db#
- * files for the backend instance.
- * restore directory is supposed to be where the backend
- * directory is located.
- */
-
- inst = ldbm_instance_find_by_name(li, (char *)direntry->name);
- if (inst == NULL)
- continue;
+ dirhandle = PR_OpenDir(real_src_dir);
+ if (NULL == dirhandle) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "Restore: failed to open the directory \"%s\"\n", real_src_dir);
+ if (task) {
+ slapi_task_log_notice(task,
+ "Restore: failed to open the directory \"%s\"\n", real_src_dir);
+ }
+ return_value = -1;
+ goto error_out;
+ }
+
+ while (NULL !=
+ (direntry = PR_ReadDir(dirhandle, PR_SKIP_DOT | PR_SKIP_DOT_DOT))) {
+ if (NULL == direntry->name) {
+ /* NSPR doesn't behave like the docs say it should */
+ break;
+ }
- restore_dir = inst->inst_parent_dir_name;
- /* If we're doing a partial restore, we need to reset the LSNs on the data files */
- if (dblayer_copy_directory(li, task, filename1,
- restore_dir, 1 /* restore */, &cnt, 0, 0, (bename) ? 1 : 0) == 0)
- continue;
- else
- {
- LDAPDebug(LDAP_DEBUG_ANY,
- "restore: failed to copy directory %s\n",
- filename1, 0, 0);
+ /* Is this entry a directory? */
+ PR_snprintf(filename1, sizeof(filename1), "%s/%s",
+ real_src_dir, direntry->name);
+ tmp_rval = PR_GetFileInfo(filename1, &info);
+ if (tmp_rval == PR_SUCCESS && PR_FILE_DIRECTORY == info.type) {
+ /* This is an instance directory. It contains the *.db#
+ * files for the backend instance.
+ * restore directory is supposed to be where the backend
+ * directory is located.
+ */
+ if (0 == strcmp(CHANGELOG_BACKUPDIR, direntry->name)) {
+ if (changelogdir) {
+ char *cldirname = PL_strrchr(changelogdir, '/');
+ char *p = filename1 + strlen(filename1);
+ if (NULL == cldirname) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "Restore: broken changelog dir path %s\n",
+ changelogdir);
if (task) {
slapi_task_log_notice(task,
- "Failed to copy directory %s", filename1);
+ "Restore: broken changelog dir path %s\n",
+ changelogdir);
}
- break;
+ goto error_out;
+ }
+ PR_snprintf(p, sizeof(filename1) - (p - filename1),
+ "/%s", cldirname+1);
+ /* Get the parent dir of changelogdir */
+ *cldirname = '\0';
+ return_value = dblayer_copy_directory(li, task, filename1,
+ changelogdir, 1 /* restore */, &cnt, 0, 0, 0);
+ *cldirname = '/';
+ if (return_value) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "Restore: failed to copy directory %s\n",
+ filename1);
+ if (task) {
+ slapi_task_log_notice(task,
+ "Restore: failed to copy directory %s",
+ filename1);
+ }
+ goto error_out;
}
+ /* Copy DBVERSION */
+ p = filename1 + strlen(filename1);
+ PR_snprintf(p, sizeof(filename1) - (p - filename1),
+ "/%s", DBVERSION_FILENAME);
+ PR_snprintf(filename2, sizeof(filename2), "%s/%s",
+ changelogdir, DBVERSION_FILENAME);
+ return_value = dblayer_copyfile(filename1, filename2,
+ 0, priv->dblayer_file_mode);
}
+ continue;
+ }
- if (doskip(direntry->name))
- continue;
+ inst = ldbm_instance_find_by_name(li, (char *)direntry->name);
+ if (inst == NULL)
+ continue;
- /* Is this a log file ? */
- /* Log files have names of the form "log.xxxxx" */
- /* We detect these by looking for the prefix "log." and
- * the lack of the ".db#" suffix */
- is_a_logfile = dblayer_is_logfilename(direntry->name);
- if (is_a_logfile) {
- seen_logfiles = 1;
- }
- if (is_a_logfile && (NULL != priv->dblayer_log_directory) &&
- (0 != strlen(priv->dblayer_log_directory)) ) {
- prefix = priv->dblayer_log_directory;
- } else {
- prefix = home_dir;
- }
- mkdir_p(prefix, 0700);
- PR_snprintf(filename1, MAXPATHLEN, "%s/%s", real_src_dir, direntry->name);
- PR_snprintf(filename2, MAXPATHLEN, "%s/%s", prefix, direntry->name);
- LDAPDebug(LDAP_DEBUG_ANY, "Restoring file %d (%s)\n",
- cnt, filename2, 0);
+ restore_dir = inst->inst_parent_dir_name;
+ /* If we're doing a partial restore, we need to reset the LSNs on the data files */
+ if (dblayer_copy_directory(li, task, filename1,
+ restore_dir, 1 /* restore */, &cnt, 0, 0, (bename) ? 1 : 0) == 0)
+ continue;
+ else
+ {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "Restore: failed to copy directory %s\n",
+ filename1);
if (task) {
- slapi_task_log_notice(task, "Restoring file %d (%s)",
- cnt, filename2);
- slapi_task_log_status(task, "Restoring file %d (%s)",
- cnt, filename2);
+ slapi_task_log_notice(task,
+ "Restore: failed to copy directory %s", filename1);
}
- return_value = dblayer_copyfile(filename1, filename2, 0,
- priv->dblayer_file_mode);
- if (0 > return_value)
- break;
-
- cnt++;
+ goto error_out;
}
- PR_CloseDir(dirhandle);
}
+
+ if (doskip(direntry->name))
+ continue;
+
+ /* Is this a log file ? */
+ /* Log files have names of the form "log.xxxxx" */
+ /* We detect these by looking for the prefix "log." and
+ * the lack of the ".db#" suffix */
+ is_a_logfile = dblayer_is_logfilename(direntry->name);
+ if (is_a_logfile) {
+ seen_logfiles = 1;
+ }
+ if (is_a_logfile && (NULL != priv->dblayer_log_directory) &&
+ (0 != strlen(priv->dblayer_log_directory)) ) {
+ prefix = priv->dblayer_log_directory;
+ } else {
+ prefix = home_dir;
+ }
+ mkdir_p(prefix, 0700);
+ PR_snprintf(filename1, sizeof(filename1), "%s/%s",
+ real_src_dir, direntry->name);
+ PR_snprintf(filename2, sizeof(filename2), "%s/%s",
+ prefix, direntry->name);
+ LDAPDebug2Args(LDAP_DEBUG_ANY, "Restoring file %d (%s)\n",
+ cnt, filename2);
+ if (task) {
+ slapi_task_log_notice(task, "Restoring file %d (%s)",
+ cnt, filename2);
+ slapi_task_log_status(task, "Restoring file %d (%s)",
+ cnt, filename2);
+ }
+ return_value = dblayer_copyfile(filename1, filename2, 0,
+ priv->dblayer_file_mode);
+ if (0 > return_value) {
+ goto error_out;
+ }
+ cnt++;
}
+ PR_CloseDir(dirhandle);
+
/* We're done ! */
/* [605024] check the DBVERSION and reset idl-switch if needed */
@@ -5802,8 +6052,8 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
if (dbversion_read(li, home_dir, &ldbmversion, &dataversion) != 0)
{
- LDAPDebug(LDAP_DEBUG_ANY, "Warning: Unable to read dbversion "
- "file in %s\n", home_dir, 0, 0);
+ LDAPDebug1Arg(LDAP_DEBUG_ANY, "Warning: Unable to read dbversion "
+ "file in %s\n", home_dir);
}
else
{
@@ -5862,10 +6112,10 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
tmp_rval = dblayer_start(li, dbmode);
if (0 != tmp_rval) {
- LDAPDebug(LDAP_DEBUG_ANY,
- "dblayer_restore: Failed to init database\n", 0, 0, 0);
+ LDAPDebug0Args(LDAP_DEBUG_ANY,
+ "Restore: failed to init database\n");
if (task) {
- slapi_task_log_notice(task, "Failed to init database");
+ slapi_task_log_notice(task, "Restore: failed to init database");
}
return_value = tmp_rval;
goto error_out;
@@ -5875,16 +6125,16 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
/* check the DSE_* files, if any */
tmp_rval = dse_conf_verify(li, real_src_dir, bename);
if (0 != tmp_rval)
- LDAPDebug(LDAP_DEBUG_ANY,
- "Warning: Unable to verify the index configuration\n", 0, 0, 0);
+ LDAPDebug0Args(LDAP_DEBUG_ANY,
+ "Warning: Unable to verify the index configuration\n");
}
if (li->li_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE) {
/* command line: close the database down again */
tmp_rval = dblayer_close(li, dbmode);
if (0 != tmp_rval) {
- LDAPDebug(LDAP_DEBUG_ANY,
- "dblayer_restore: Failed to close database\n", 0, 0, 0);
+ LDAPDebug0Args(LDAP_DEBUG_ANY,
+ "Restore: Failed to close database\n");
}
} else {
allinstance_set_busy(li); /* on-line mode */
@@ -5894,20 +6144,24 @@ int dblayer_restore(struct ldbminfo *li, char *src_dir, Slapi_Task *task, char *
error_out:
/* Free the restore src dir, but only if we allocated it above */
- if (real_src_dir != src_dir) {
+ if (real_src_dir && (real_src_dir != src_dir)) {
/* If this was an FRI restore and the staging area exists, go ahead and remove it */
if (frirestore && PR_Access(real_src_dir, PR_ACCESS_EXISTS) == PR_SUCCESS)
{
int ret1 = 0;
- LDAPDebug(LDAP_DEBUG_ANY, "dblayer_restore: Removing staging area %s.\n",real_src_dir, 0, 0);
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "Restore: Removing staging area %s.\n", real_src_dir);
ret1 = ldbm_delete_dirs(real_src_dir);
if (ret1)
{
- LDAPDebug(LDAP_DEBUG_ANY, "dblayer_restore: Removal of staging area %s failed!\n", real_src_dir, 0, 0);
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "Restore: Removal of staging area %s failed!\n",
+ real_src_dir);
}
}
- slapi_ch_free((void**)&real_src_dir);
+ slapi_ch_free_string(&real_src_dir);
}
+ slapi_ch_free_string(&changelogdir);
return return_value;
}
@@ -6136,3 +6390,60 @@ void dblayer_set_recovery_required(struct ldbminfo *li)
li->li_dblayer_private->dblayer_recovery_required = 1;
}
+int
+ldbm_back_get_info(Slapi_Backend *be, int cmd, void **info)
+{
+ int rc = -1;
+ if (!be || !info) {
+ return rc;
+ }
+
+ switch (cmd) {
+ case BACK_INFO_DBENV:
+ {
+ struct ldbminfo *li = (struct ldbminfo *)be->be_database->plg_private;
+ if (li) {
+ dblayer_private *prv = (dblayer_private*)li->li_dblayer_private;
+ if (prv && prv->dblayer_env && prv->dblayer_env->dblayer_DB_ENV) {
+ *(DB_ENV **)info = prv->dblayer_env->dblayer_DB_ENV;
+ rc = 0;
+ }
+ }
+ break;
+ }
+ case BACK_INFO_INDEXPAGESIZE:
+ {
+ struct ldbminfo *li = (struct ldbminfo *)be->be_database->plg_private;
+ if (li) {
+ dblayer_private *prv = (dblayer_private*)li->li_dblayer_private;
+ if (prv && prv->dblayer_index_page_size) {
+ *(size_t *)info = prv->dblayer_index_page_size;
+ } else {
+ *(size_t *)info = DBLAYER_INDEX_PAGESIZE;
+ }
+ rc = 0;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ return rc;
+}
+
+int
+ldbm_back_set_info(Slapi_Backend *be, int cmd, void *info)
+{
+ int rc = -1;
+ if (!be || !info) {
+ return rc;
+ }
+
+ switch (cmd) {
+ default:
+ break;
+ }
+
+ return rc;
+}
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.h b/ldap/servers/slapd/back-ldbm/dblayer.h
index d0d05b4a..419b263b 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.h
+++ b/ldap/servers/slapd/back-ldbm/dblayer.h
@@ -207,4 +207,8 @@ void dblayer_set_env_debugging(DB_ENV *pEnv, dblayer_private *priv);
/* Return the last four characters of a string; used for comparing extensions. */
char* last_four_chars(const char* s);
+/* To support backingup/restoring changelog dir */
+#define CHANGELOGENTRY "cn=changelog5,cn=config"
+#define CHANGELOGDIRATTR "nsslapd-changelogdir"
+
#endif /* _DBLAYER_H_ */
diff --git a/ldap/servers/slapd/back-ldbm/import-threads.c b/ldap/servers/slapd/back-ldbm/import-threads.c
index 1fc269b9..1d490546 100644
--- a/ldap/servers/slapd/back-ldbm/import-threads.c
+++ b/ldap/servers/slapd/back-ldbm/import-threads.c
@@ -549,6 +549,7 @@ import_producer(void *param)
}
continue;
}
+ /* From here, e != NULL */
if (0 == my_version) {
/* after the first entry version string won't be given */
my_version = -1;
@@ -556,10 +557,7 @@ import_producer(void *param)
if (! import_entry_belongs_here(e, inst->inst_be)) {
/* silently skip */
- if (e) {
- slapi_entry_free(e);
- }
-
+ slapi_entry_free(e);
continue;
}
@@ -569,9 +567,7 @@ import_producer(void *param)
"violates schema, ending line %d of file "
"\"%s\"", escape_string(slapi_entry_get_dn(e), ebuf),
curr_lineno, curr_filename);
- if (e) {
- slapi_entry_free(e);
- }
+ slapi_entry_free(e);
job->skipped++;
continue;
@@ -625,9 +621,7 @@ import_producer(void *param)
"violates attribute syntax, ending line %d of "
"file \"%s\"", escape_string(slapi_entry_get_dn(e), ebuf),
curr_lineno, curr_filename);
- if (e) {
- slapi_entry_free(e);
- }
+ slapi_entry_free(e);
job->skipped++;
continue;
@@ -640,8 +634,10 @@ import_producer(void *param)
}
ep = import_make_backentry(e, id);
- if (!ep || !ep->ep_entry)
+ if (!ep) {
+ slapi_entry_free(e);
goto error;
+ }
/* check for include/exclude subtree lists */
if (! ldbm_back_ok_to_dump(backentry_get_ndn(ep),
@@ -729,8 +725,8 @@ import_producer(void *param)
"ending line %d of file \"%s\"",
escape_string(slapi_entry_get_dn(e), ebuf),
curr_lineno, curr_filename);
- import_log_notice(job, "REASON: entry too large (%ld bytes) for "
- "the buffer size (%lu bytes)", newesize, job->fifo.bsize);
+ import_log_notice(job, "REASON: entry too large (%u bytes) for "
+ "the buffer size (%u bytes)", newesize, job->fifo.bsize);
backentry_free(&ep);
job->skipped++;
continue;
@@ -1422,6 +1418,7 @@ upgradedn_producer(void *param)
continue;
}
+ /* From here, e != NULL */
/* Check DN syntax attr values if it contains '\\' or not */
/* Start from the rdn */
if (entryrdn_get_switch()) { /* subtree-rename: on */
@@ -1615,7 +1612,7 @@ upgradedn_producer(void *param)
upgradedn_free_list(&ud_list);
ep = import_make_backentry(e, temp_id);
- if (!ep || !ep->ep_entry) {
+ if (!ep) {
slapi_entry_free(e); e = NULL;
goto error;
}
@@ -2130,7 +2127,7 @@ import_foreman(void *param)
* Note: FLAG_UPGRADEDNFORMAT only.
*/
Slapi_Attr *orig_entrydn = NULL;
- Slapi_Attr *new_entrydn = slapi_attr_new();
+ Slapi_Attr *new_entrydn = NULL;
Slapi_Attr *nsuniqueid = NULL;
const char *uuidstr = NULL;
char *new_dn = NULL;
@@ -2150,6 +2147,7 @@ import_foreman(void *param)
orig_dn, fi->entry->ep_id);
goto cont;
}
+ new_entrydn = slapi_attr_new();
new_dn = slapi_create_dn_string("nsuniqueid=%s+%s",
uuidstr, orig_dn);
/* releasing original dn */
@@ -2724,6 +2722,10 @@ static int bulk_import_queue(ImportJob *job, Slapi_Entry *entry)
Slapi_Attr *attr = NULL;
size_t newesize = 0;
+ if (!entry) {
+ return -1;
+ }
+
PR_Lock(job->wire_lock);
/* Let's do this inside the lock !*/
id = job->lead_ID + 1;
@@ -2732,7 +2734,7 @@ static int bulk_import_queue(ImportJob *job, Slapi_Entry *entry)
/* make into backentry */
ep = import_make_backentry(entry, id);
- if (!ep || !ep->ep_entry) {
+ if (!ep) {
import_abort_all(job, 1);
PR_Unlock(job->wire_lock);
return -1;
@@ -3157,9 +3159,10 @@ dse_conf_verify_core(struct ldbminfo *li, char *src_dir, char *file_name, char *
if (entry_filter != NULL) /* Single instance restoration */
{
- if (NULL == strstr(estr, entry_filter))
+ if (NULL == strstr(estr, entry_filter)) {
slapi_ch_free_string(&estr);
continue;
+ }
}
e = slapi_str2entry(estr, 0);
diff --git a/ldap/servers/slapd/back-ldbm/init.c b/ldap/servers/slapd/back-ldbm/init.c
index f1f71840..83951aea 100644
--- a/ldap/servers/slapd/back-ldbm/init.c
+++ b/ldap/servers/slapd/back-ldbm/init.c
@@ -248,6 +248,10 @@ ldbm_back_init( Slapi_PBlock *pb )
(void *) ldbm_back_wire_import );
rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_ADD_SCHEMA_FN,
(void *) ldbm_back_add_schema );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_GET_INFO_FN,
+ (void *) ldbm_back_get_info );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_SET_INFO_FN,
+ (void *) ldbm_back_set_info );
if ( rc != 0 ) {
LDAPDebug( LDAP_DEBUG_ANY, "ldbm_back_init failed\n", 0, 0, 0 );
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
index 529f55e0..5e3b9b53 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
@@ -190,7 +190,7 @@ int
ldbm_back_modify( Slapi_PBlock *pb )
{
backend *be;
- ldbm_instance *inst;
+ ldbm_instance *inst = NULL;
struct ldbminfo *li;
struct backentry *e = NULL, *ec = NULL;
Slapi_Entry *postentry = NULL;
diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
index 25cc265c..e0b09fb4 100644
--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
@@ -1389,6 +1389,7 @@ ldbm_back_ldbm2ldif( Slapi_PBlock *pb )
&eargs, DB2LDIF_ENTRYRDN, &psrdn);
if (rc) {
slapi_rdn_done(&psrdn);
+ backentry_free(&ep);
continue;
}
}
@@ -1424,6 +1425,7 @@ ldbm_back_ldbm2ldif( Slapi_PBlock *pb )
"%d\n", pid);
slapi_ch_free_string(&rdn);
slapi_rdn_done(&psrdn);
+ backentry_free(&ep);
continue;
}
}
@@ -1436,6 +1438,7 @@ ldbm_back_ldbm2ldif( Slapi_PBlock *pb )
rdn, temp_id);
slapi_ch_free_string(&rdn);
slapi_rdn_done(&psrdn);
+ backentry_free(&ep);
continue;
}
}
@@ -1932,6 +1935,7 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb)
rdn, temp_id, pid, run_from_cmdline,
NULL, index_ext, &psrdn);
if (rc) {
+ backentry_free(&ep);
continue;
}
}
@@ -1966,6 +1970,7 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb)
"%d\n", pid);
slapi_ch_free_string(&rdn);
slapi_rdn_done(&psrdn);
+ backentry_free(&ep);
continue;
}
}
@@ -1978,6 +1983,7 @@ ldbm_back_ldbm2index(Slapi_PBlock *pb)
rdn, temp_id);
slapi_ch_free_string(&rdn);
slapi_rdn_done(&psrdn);
+ backentry_free(&ep);
continue;
}
}
@@ -2448,7 +2454,6 @@ ldbm_exclude_attr_from_export( struct ldbminfo *li , const char *attr,
int upgradedb_core(Slapi_PBlock *pb, ldbm_instance *inst);
int upgradedb_copy_logfiles(struct ldbminfo *li, char *destination_dir, int restore);
int upgradedb_delete_indices_4cmd(ldbm_instance *inst, int flags);
-static void normalize_dir(char *dir);
/*
* ldbm_back_upgradedb -
@@ -2797,26 +2802,6 @@ fail0:
return rval + upgrade_rval;
}
-static void
-normalize_dir(char *dir)
-{
- char *p = NULL;
- int l = 0;
-
- if (NULL == dir) {
- return;
- }
- l = strlen(dir);
-
- for (p = dir + l - 1; p && *p; p--) {
- if (' ' != *p && '\t' != *p && '/' != *p && '\\' != *p) {
- break;
- }
- }
- *(p+1) = '\0';
-}
-
-
#define LOG "log."
#define LOGLEN 4
int upgradedb_copy_logfiles(struct ldbminfo *li, char *destination_dir,
@@ -3070,7 +3055,7 @@ _get_and_add_parent_rdns(backend *be,
slapi_log_error(SLAPI_LOG_FATAL, "ldif2dbm",
"_get_and_add_parent_rdns: "
"Failed to convert DN %s to RDN\n",
- slapi_sdn_get_dn(bdn->dn_sdn));
+ slapi_rdn_get_rdn(&mysrdn));
slapi_rdn_done(&mysrdn);
CACHE_RETURN(&inst->inst_dncache, &bdn);
goto bail;
@@ -3162,7 +3147,7 @@ _get_and_add_parent_rdns(backend *be,
slapi_log_error(SLAPI_LOG_FATAL, "ldif2dbm",
"_get_and_add_parent_rdns: "
"Failed to merge Slapi_RDN %s to RDN\n",
- slapi_sdn_get_dn(bdn->dn_sdn));
+ slapi_rdn_get_rdn(&mysrdn));
goto bail;
}
}
diff --git a/ldap/servers/slapd/back-ldbm/misc.c b/ldap/servers/slapd/back-ldbm/misc.c
index 4b4a7200..13b87fd7 100644
--- a/ldap/servers/slapd/back-ldbm/misc.c
+++ b/ldap/servers/slapd/back-ldbm/misc.c
@@ -483,12 +483,14 @@ get_value_from_string(const char *string, char *type, char **value)
ldif_getline_fixline(startptr, tmpptr);
startptr = tmpptr;
rc = slapi_ldif_parse_line(copy, &tmptype, &bvvalue, &freeval);
- if (0 > rc || NULL == bvvalue.bv_val || 0 >= bvvalue.bv_len) {
+ if (0 > rc || NULL == tmptype.bv_val ||
+ NULL == bvvalue.bv_val || 0 >= bvvalue.bv_len) {
slapi_log_error(SLAPI_LOG_FATAL, "get_value_from_string", "parse "
"failed: %d\n", rc);
if (freeval) {
slapi_ch_free_string(&bvvalue.bv_val);
}
+ rc = -1; /* set non-0 to rc */
goto bail;
}
if (0 != PL_strncasecmp(type, tmptype.bv_val, tmptype.bv_len)) {
@@ -498,8 +500,10 @@ get_value_from_string(const char *string, char *type, char **value)
if (freeval) {
slapi_ch_free_string(&bvvalue.bv_val);
}
+ rc = -1; /* set non-0 to rc */
goto bail;
}
+ rc = 0; /* set 0 to rc */
if (freeval) {
*value = bvvalue.bv_val; /* just hand off the memory */
bvvalue.bv_val = NULL;
@@ -609,3 +613,23 @@ bail:
slapi_ch_free_string(&copy);
return rc;
}
+
+void
+normalize_dir(char *dir)
+{
+ char *p = NULL;
+ int l = 0;
+
+ if (NULL == dir) {
+ return;
+ }
+ l = strlen(dir);
+
+ for (p = dir + l - 1; p && *p && (p > dir); p--) {
+ if ((' ' != *p) && ('\t' != *p) && ('/' != *p) && ('\\' != *p)) {
+ break;
+ }
+ }
+ *(p+1) = '\0';
+}
+
diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
index 615d9373..363bec27 100644
--- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
@@ -173,6 +173,9 @@ int dblayer_db_uses_logging(DB_ENV *db_env);
int dblayer_bt_compare(DB *db, const DBT *dbt1, const DBT *dbt2);
int dblayer_remove_env(struct ldbminfo *li);
+int ldbm_back_get_info(Slapi_Backend *be, int cmd, void **info);
+int ldbm_back_set_info(Slapi_Backend *be, int cmd, void *info);
+
/*
* dn2entry.c
*/
@@ -364,7 +367,7 @@ int is_fullpath(char *path);
char get_sep(char *path);
int get_value_from_string(const char *string, char *type, char **value);
int get_values_from_string(const char *string, char *type, char ***valuearray);
-
+void normalize_dir(char *dir);
/*
* nextid.c
diff --git a/ldap/servers/slapd/backend.c b/ldap/servers/slapd/backend.c
index 087f437a..9bdc0aff 100644
--- a/ldap/servers/slapd/backend.c
+++ b/ldap/servers/slapd/backend.c
@@ -581,3 +581,25 @@ void be_set_timelimit(Slapi_Backend * be, int timelimit)
{
be->be_timelimit = timelimit;
}
+
+int
+slapi_back_get_info(Slapi_Backend *be, int cmd, void **info)
+{
+ int rc = -1;
+ if (!be || !be->be_get_info || !info) {
+ return rc;
+ }
+ rc = (*be->be_get_info)(be, cmd, info);
+ return rc;
+}
+
+int
+slapi_back_set_info(Slapi_Backend *be, int cmd, void *info)
+{
+ int rc = -1;
+ if (!be || !be->be_set_info || !info) {
+ return rc;
+ }
+ rc = (*be->be_set_info)(be, cmd, info);
+ return rc;
+}
diff --git a/ldap/servers/slapd/pblock.c b/ldap/servers/slapd/pblock.c
index c8304af8..4cc6536a 100644
--- a/ldap/servers/slapd/pblock.c
+++ b/ldap/servers/slapd/pblock.c
@@ -610,6 +610,12 @@ slapi_pblock_get( Slapi_PBlock *pblock, int arg, void *value )
case SLAPI_PLUGIN_DB_ADD_SCHEMA_FN:
(*(IFP *)value) = pblock->pb_plugin->plg_add_schema;
break;
+ case SLAPI_PLUGIN_DB_GET_INFO_FN:
+ (*(IFP *)value) = pblock->pb_plugin->plg_get_info;
+ break;
+ case SLAPI_PLUGIN_DB_SET_INFO_FN:
+ (*(IFP *)value) = pblock->pb_plugin->plg_set_info;
+ break;
case SLAPI_PLUGIN_DB_SEQ_FN:
if ( pblock->pb_plugin->plg_type != SLAPI_PLUGIN_DATABASE ) {
return( -1 );
@@ -936,6 +942,12 @@ slapi_pblock_get( Slapi_PBlock *pblock, int arg, void *value )
}
(*(IFP *)value) = pblock->pb_plugin->plg_bepredelete;
break;
+ case SLAPI_PLUGIN_BE_PRE_CLOSE_FN:
+ if (pblock->pb_plugin->plg_type != SLAPI_PLUGIN_BEPREOPERATION) {
+ return( -1 );
+ }
+ (*(IFP *)value) = pblock->pb_plugin->plg_bepreclose;
+ break;
/* backend postoperation plugin */
case SLAPI_PLUGIN_BE_POST_MODIFY_FN:
@@ -962,6 +974,12 @@ slapi_pblock_get( Slapi_PBlock *pblock, int arg, void *value )
}
(*(IFP *)value) = pblock->pb_plugin->plg_bepostdelete;
break;
+ case SLAPI_PLUGIN_BE_POST_OPEN_FN:
+ if (pblock->pb_plugin->plg_type != SLAPI_PLUGIN_BEPOSTOPERATION) {
+ return( -1 );
+ }
+ (*(IFP *)value) = pblock->pb_plugin->plg_bepostopen;
+ break;
/* internal preoperation plugin */
case SLAPI_PLUGIN_INTERNAL_PRE_MODIFY_FN:
@@ -2014,6 +2032,12 @@ slapi_pblock_set( Slapi_PBlock *pblock, int arg, void *value )
case SLAPI_PLUGIN_DB_ADD_SCHEMA_FN:
pblock->pb_plugin->plg_add_schema = (IFP) value;
break;
+ case SLAPI_PLUGIN_DB_GET_INFO_FN:
+ pblock->pb_plugin->plg_get_info = (IFP) value;
+ break;
+ case SLAPI_PLUGIN_DB_SET_INFO_FN:
+ pblock->pb_plugin->plg_set_info = (IFP) value;
+ break;
case SLAPI_PLUGIN_DB_SEQ_FN:
if ( pblock->pb_plugin->plg_type != SLAPI_PLUGIN_DATABASE ) {
return( -1 );
@@ -2332,6 +2356,12 @@ slapi_pblock_set( Slapi_PBlock *pblock, int arg, void *value )
}
pblock->pb_plugin->plg_bepredelete = (IFP) value;
break;
+ case SLAPI_PLUGIN_BE_PRE_CLOSE_FN:
+ if (pblock->pb_plugin->plg_type != SLAPI_PLUGIN_BEPREOPERATION) {
+ return( -1 );
+ }
+ pblock->pb_plugin->plg_bepreclose = (IFP) value;
+ break;
/* backend postoperation plugin */
case SLAPI_PLUGIN_BE_POST_MODIFY_FN:
@@ -2358,7 +2388,12 @@ slapi_pblock_set( Slapi_PBlock *pblock, int arg, void *value )
}
pblock->pb_plugin->plg_bepostdelete = (IFP) value;
break;
-
+ case SLAPI_PLUGIN_BE_POST_OPEN_FN:
+ if (pblock->pb_plugin->plg_type != SLAPI_PLUGIN_BEPOSTOPERATION) {
+ return( -1 );
+ }
+ pblock->pb_plugin->plg_bepostopen = (IFP) value;
+ break;
/* internal preoperation plugin */
case SLAPI_PLUGIN_INTERNAL_PRE_MODIFY_FN:
diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c
index e283a276..aa544269 100644
--- a/ldap/servers/slapd/plugin.c
+++ b/ldap/servers/slapd/plugin.c
@@ -347,6 +347,7 @@ plugin_call_plugins( Slapi_PBlock *pb, int whichfunction )
case SLAPI_PLUGIN_BE_PRE_MODRDN_FN:
case SLAPI_PLUGIN_BE_PRE_ADD_FN:
case SLAPI_PLUGIN_BE_PRE_DELETE_FN:
+ case SLAPI_PLUGIN_BE_PRE_CLOSE_FN:
plugin_list_number= PLUGIN_LIST_BEPREOPERATION;
do_op = 1; /* always allow backend callbacks (even during startup) */
break;
@@ -354,6 +355,7 @@ plugin_call_plugins( Slapi_PBlock *pb, int whichfunction )
case SLAPI_PLUGIN_BE_POST_MODRDN_FN:
case SLAPI_PLUGIN_BE_POST_ADD_FN:
case SLAPI_PLUGIN_BE_POST_DELETE_FN:
+ case SLAPI_PLUGIN_BE_POST_OPEN_FN:
plugin_list_number= PLUGIN_LIST_BEPOSTOPERATION;
do_op = 1; /* always allow backend callbacks (even during startup) */
break;
@@ -2403,8 +2405,12 @@ plugin_invoke_plugin_pb (struct slapdplugin *plugin, int operation, Slapi_PBlock
PR_ASSERT (pb);
/* we always allow initialization and cleanup operations */
- if (operation == SLAPI_PLUGIN_START_FN || operation == SLAPI_PLUGIN_POSTSTART_FN ||
- operation == SLAPI_PLUGIN_CLOSE_FN || operation == SLAPI_PLUGIN_CLEANUP_FN)
+ if (operation == SLAPI_PLUGIN_START_FN ||
+ operation == SLAPI_PLUGIN_POSTSTART_FN ||
+ operation == SLAPI_PLUGIN_CLOSE_FN ||
+ operation == SLAPI_PLUGIN_CLEANUP_FN ||
+ operation == SLAPI_PLUGIN_BE_PRE_CLOSE_FN ||
+ operation == SLAPI_PLUGIN_BE_POST_OPEN_FN)
return PR_TRUE;
PR_ASSERT (pb->pb_op);
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index e63a0b62..8a405926 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -839,6 +839,8 @@ struct slapdplugin {
IFP plg_un_db_wire_import; /* fast replica update */
IFP plg_un_db_verify; /* verify db files */
IFP plg_un_db_add_schema; /* add schema */
+ IFP plg_un_db_get_info; /* get info */
+ IFP plg_un_db_set_info; /* set info */
} plg_un_db;
#define plg_bind plg_un.plg_un_db.plg_un_db_bind
#define plg_unbind plg_un.plg_un_db.plg_un_db_unbind
@@ -874,6 +876,8 @@ struct slapdplugin {
#define plg_init_instance plg_un.plg_un_db.plg_un_db_init_instance
#define plg_wire_import plg_un.plg_un_db.plg_un_db_wire_import
#define plg_add_schema plg_un.plg_un_db.plg_un_db_add_schema
+#define plg_get_info plg_un.plg_un_db.plg_un_db_get_info
+#define plg_set_info plg_un.plg_un_db.plg_un_db_set_info
/* extended operation plugin structure */
struct plg_un_protocol_extension {
@@ -950,11 +954,13 @@ struct slapdplugin {
IFP plg_un_bepre_modrdn; /* modrdn */
IFP plg_un_bepre_add; /* add */
IFP plg_un_bepre_delete; /* delete */
+ IFP plg_un_bepre_close; /* close */
} plg_un_bepre;
#define plg_bepremodify plg_un.plg_un_bepre.plg_un_bepre_modify
#define plg_bepremodrdn plg_un.plg_un_bepre.plg_un_bepre_modrdn
#define plg_bepreadd plg_un.plg_un_bepre.plg_un_bepre_add
#define plg_bepredelete plg_un.plg_un_bepre.plg_un_bepre_delete
+#define plg_bepreclose plg_un.plg_un_bepre.plg_un_bepre_close
/* backend post-operation plugin structure */
struct plg_un_bepost_operation {
@@ -962,11 +968,13 @@ struct slapdplugin {
IFP plg_un_bepost_modrdn; /* modrdn */
IFP plg_un_bepost_add; /* add */
IFP plg_un_bepost_delete; /* delete */
+ IFP plg_un_bepost_open; /* open */
} plg_un_bepost;
#define plg_bepostmodify plg_un.plg_un_bepost.plg_un_bepost_modify
#define plg_bepostmodrdn plg_un.plg_un_bepost.plg_un_bepost_modrdn
#define plg_bepostadd plg_un.plg_un_bepost.plg_un_bepost_add
#define plg_bepostdelete plg_un.plg_un_bepost.plg_un_bepost_delete
+#define plg_bepostopen plg_un.plg_un_bepost.plg_un_bepost_open
/* internal pre-operation plugin structure */
struct plg_un_internal_pre_operation {
@@ -1148,6 +1156,8 @@ typedef struct backend {
#define be_init_instance be_database->plg_init_instance
#define be_cleanup be_database->plg_cleanup
#define be_wire_import be_database->plg_wire_import
+#define be_get_info be_database->plg_get_info
+#define be_set_info be_database->plg_set_info
void *be_instance_info; /* If the database plugin pointed to by
* be_database supports more than one instance,
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 0aab49ca..3dd92e0f 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -5250,6 +5250,7 @@ int slapi_is_root_suffix(Slapi_DN * dn);
const Slapi_DN *slapi_get_suffix_by_dn(const Slapi_DN *dn);
const char * slapi_be_gettype(Slapi_Backend *be);
+
int slapi_be_is_flag_set(Slapi_Backend * be, int flag);
void slapi_be_set_flag(Slapi_Backend * be, int flag);
#define SLAPI_BE_FLAG_REMOTE_DATA 0x1 /* entries held by backend are remote */
@@ -5687,6 +5688,7 @@ typedef struct slapi_plugindesc {
#define SLAPI_PLUGIN_BE_PRE_MODIFY_FN 451
#define SLAPI_PLUGIN_BE_PRE_MODRDN_FN 452
#define SLAPI_PLUGIN_BE_PRE_DELETE_FN 453
+#define SLAPI_PLUGIN_BE_PRE_CLOSE_FN 454
/* postoperation plugin functions */
#define SLAPI_PLUGIN_POST_BIND_FN 501
@@ -5714,6 +5716,7 @@ typedef struct slapi_plugindesc {
#define SLAPI_PLUGIN_BE_POST_MODIFY_FN 551
#define SLAPI_PLUGIN_BE_POST_MODRDN_FN 552
#define SLAPI_PLUGIN_BE_POST_DELETE_FN 553
+#define SLAPI_PLUGIN_BE_POST_OPEN_FN 554
/* matching rule plugin functions */
#define SLAPI_PLUGIN_MR_FILTER_CREATE_FN 600
@@ -6195,11 +6198,45 @@ int slapi_set_plugin_default_config(const char *type, Slapi_Value *value);
* \return \c 0 if the operation was successful
* \return non-0 if the operation was not successful
* \warning Caller is responsible to free attrs by slapi_ch_array_free
- * */
+ */
int slapi_get_plugin_default_config(char *type, Slapi_ValueSet **valueset);
int slapi_check_account_lock( Slapi_PBlock *pb, Slapi_Entry *bind_target_entry, int pwresponse_req, int check_password_policy, int send_result);
+/* backend get/set info */
+/**
+ * Get backend info based upon cmd
+ *
+ * \param be Backend from which the infomation will be retrieved
+ * \param cmd macro to specify the information type
+ * \param info pointer to store the information
+ * \return \c 0 if the operation was successful
+ * \return non-0 if the operation was not successful
+ *
+ * \note Implemented cmd:
+ * BACK_INFO_DBENV - Get the dbenv
+ */
+int slapi_back_get_info(Slapi_Backend *be, int cmd, void **info);
+
+/**
+ * Set info to backend based upon cmd
+ *
+ * \param be Backend to which the infomation will be set
+ * \param cmd macro to specify the information type
+ * \param info pointer to the information
+ * \return \c 0 if the operation was successful
+ * \return non-0 if the operation was not successful
+ * \warning No cmd is defined yet.
+ */
+int slapi_back_set_info(Slapi_Backend *be, int cmd, void *info);
+
+/* cmd */
+enum
+{
+ BACK_INFO_DBENV, /* Get the dbenv */
+ BACK_INFO_INDEXPAGESIZE /* Get the index page size */
+};
+
#ifdef __cplusplus
}
#endif
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
index bd34ec85..d6c5c6f3 100644
--- a/ldap/servers/slapd/slapi-private.h
+++ b/ldap/servers/slapd/slapi-private.h
@@ -878,6 +878,8 @@ int valuearray_normalize_value(Slapi_Value **vals);
/* database plugin-specific parameters */
#define SLAPI_PLUGIN_DB_NO_ACL 250
#define SLAPI_PLUGIN_DB_RMDB_FN 280
+#define SLAPI_PLUGIN_DB_GET_INFO_FN 290
+#define SLAPI_PLUGIN_DB_SET_INFO_FN 291
/**** End of database plugin interface. **************************************/