diff options
| author | Noriko Hosoi <nhosoi@redhat.com> | 2007-03-15 21:40:34 +0000 |
|---|---|---|
| committer | Noriko Hosoi <nhosoi@redhat.com> | 2007-03-15 21:40:34 +0000 |
| commit | 30ef36de95df4bedcd41a0470cccb45a553ba2c4 (patch) | |
| tree | dd32df82ebb22938c04bbd26b9aff90ac8ece471 | |
| parent | d155d05b4648a4803dab0306b6249f2d4cdf9610 (diff) | |
| download | ds-30ef36de95df4bedcd41a0470cccb45a553ba2c4.tar.gz ds-30ef36de95df4bedcd41a0470cccb45a553ba2c4.tar.xz ds-30ef36de95df4bedcd41a0470cccb45a553ba2c4.zip | |
Resolves: 232050
Summary: Change format of DBVERSION and guardian files (Comment #6)
1) introduced new strings for DBVERSION
2) added the logic to compare the new DBVERSION strings
note: we don't store the current db version string in the replication
code any more. Instead, we get it from Berkeley DB header file db.h.
| -rw-r--r-- | ldap/servers/plugins/replication/cl5_api.c | 218 | ||||
| -rw-r--r-- | ldap/servers/plugins/replication/cl5_api.h | 4 | ||||
| -rw-r--r-- | ldap/servers/plugins/replication/repl_shared.h | 7 |
3 files changed, 186 insertions, 43 deletions
diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c index 0897ff0b..4c45ec6a 100644 --- a/ldap/servers/plugins/replication/cl5_api.c +++ b/ldap/servers/plugins/replication/cl5_api.c @@ -62,8 +62,6 @@ #include "cl5_clcache.h" /* To use the Changelog Cache */ #include "repl5.h" /* for agmt_get_consumer_rid() */ -#define CL5_TYPE "Changelog5" /* changelog type */ -#define VERSION_SIZE 127 /* size of the buffer to hold changelog version */ #define GUARDIAN_FILE "guardian" /* name of the guardian file */ #define VERSION_FILE "DBVERSION" /* name of the version file */ #define MAX_TRIALS 50 /* number of retries on db operations */ @@ -287,7 +285,7 @@ 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); +static int _cl5ReadDBVersion (const char *dir, char *clVersion, int buflen); static int _cl5WriteDBVersion (); static int _cl5CheckGuardian (); static int _cl5ReadGuardian (char *buff); @@ -2214,6 +2212,52 @@ static int _cl5RemoveEnv () return CL5_SUCCESS; } +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; + } + 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; +} + static int _cl5AppInit (PRBool *didRecovery) { int rc; @@ -2286,7 +2330,10 @@ static int _cl5AppInit (PRBool *didRecovery) if ((flags & DB_RECOVER) || (flags & DB_RECOVER_FATAL)) { if (CL5_OPEN_CLEAN_RECOVER == s_cl5Desc.dbOpenMode) + { _cl5RemoveEnv(); + _cl5RemoveLogs(); + } rc = _cl5Recover (flags, dbEnv); if (rc != CL5_SUCCESS) @@ -3219,7 +3266,8 @@ static int _cl5TrickleMain (void *param) /* 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 - * 3. extention .db3 -> .db4 ### koko kara !!! + * 3. Remove any Berkeley DB transaction log files + * 4. extention .db3 -> .db4 */ static int _cl5Upgrade3_4(char *fromVersion, char *toVersion) { @@ -3239,6 +3287,7 @@ static int _cl5Upgrade3_4(char *fromVersion, char *toVersion) "_cl5Upgrade3_4: failed to open the db env\n"); return rc; } + s_cl5Desc.dbOpenMode = backup; dir = PR_OpenDir(s_cl5Desc.dbDir); if (dir == NULL) @@ -3317,6 +3366,48 @@ out: return rc; } +/* upgrade from db41 -> db42 -> db43 -> db44 -> db45 + * 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 + * 3. Remove any Berkeley DB transaction log files + */ +static int _cl5Upgrade4_4(char *fromVersion, char *toVersion) +{ + PRDirEntry *entry = NULL; + DB *thisdb = NULL; + CL5OpenMode backup; + int rc = 0; + + backup = s_cl5Desc.dbOpenMode; + s_cl5Desc.dbOpenMode = CL5_OPEN_CLEAN_RECOVER; + /* CL5_OPEN_CLEAN_RECOVER does 1 and 2 */ + rc = _cl5AppInit (NULL); + if (rc != CL5_SUCCESS) + { + slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, + "_cl5Upgrade4_4: failed to open the db env\n"); + return rc; + } + s_cl5Desc.dbOpenMode = backup; + + /* 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; +} + static int _cl5CheckDBVersion () { char clVersion [VERSION_SIZE + 1]; @@ -3332,48 +3423,87 @@ static int _cl5CheckDBVersion () } } else - { - PR_snprintf (clVersion, VERSION_SIZE, "%s/%s/%s", CL5_TYPE, REPL_PLUGIN_NAME, - CHANGELOG_DB_VERSION); - rc = _cl5ReadDBVersion (s_cl5Desc.dbDir, dbVersion); + { + char *versionp = NULL; + char *versionendp = NULL; + char *dotp = NULL; + int dbmajor = 0; + int dbminor = 0; + + PR_snprintf (clVersion, VERSION_SIZE, "%s/%d.%d/%s", + BDB_IMPL, DB_VERSION_MAJOR, DB_VERSION_MINOR, BDB_REPLPLUGIN); + + rc = _cl5ReadDBVersion (s_cl5Desc.dbDir, dbVersion, sizeof(dbVersion)); if (rc != CL5_SUCCESS) { slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, "_cl5CheckDBVersion: invalid dbversion\n"); rc = CL5_BAD_DBVERSION; + goto bailout; + } + versionendp = dbVersion + strlen(dbVersion); + /* get the version number */ + /* old DBVERSION string: CL5_TYPE/REPL_PLUGIN_NAME/#.# */ + if (PL_strncmp(dbVersion, CL5_TYPE, strlen(CL5_TYPE)) == 0) + { + versionp = strrchr(dbVersion, '/'); + } + /* new DBVERSION string: bdb/#.#/libreplication-plugin */ + else if (PL_strncmp(dbVersion, BDB_IMPL, strlen(BDB_IMPL)) == 0) + { + versionp = strchr(dbVersion, '/'); + } + if (NULL == versionp || versionp == versionendp) + { + slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, + "_cl5CheckDBVersion: invalid dbversion: %s\n", dbVersion); + rc = CL5_BAD_DBVERSION; + goto bailout; + } + dotp = strchr(++versionp, '.'); + if (NULL != dotp) + { + *dotp = '\0'; + dbmajor = strtol(versionp, (char **)NULL, 10); + dbminor = strtol(++dotp, (char **)NULL, 10); + *dotp = '.'; + } + else + { + dbmajor = strtol(versionp, (char **)NULL, 10); } - else if (strcasecmp (clVersion, dbVersion) != 0) + + if (dbmajor < DB_VERSION_MAJOR) { - char prevClVersion [VERSION_SIZE + 1]; - PR_snprintf (prevClVersion, VERSION_SIZE, "%s/%s/%s", - CL5_TYPE, REPL_PLUGIN_NAME, CHANGELOG_DB_VERSION_PREV); - if (strcasecmp (prevClVersion, dbVersion) == 0) + /* upgrade */ + rc = _cl5Upgrade3_4(dbVersion, clVersion); + if (rc != CL5_SUCCESS) { - /* upgrade */ - rc = _cl5Upgrade3_4(prevClVersion, clVersion); - if (rc != CL5_SUCCESS) - { - slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, + slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, "_cl5CheckDBVersion: upgrade %s -> %s failed\n", - CHANGELOG_DB_VERSION_PREV, CHANGELOG_DB_VERSION); - rc = CL5_BAD_DBVERSION; - } + dbVersion, clVersion); + rc = CL5_BAD_DBVERSION; } - else + } + else if (dbminor < DB_VERSION_MINOR) + { + /* minor upgrade */ + rc = _cl5Upgrade4_4(dbVersion, clVersion); + if (rc != CL5_SUCCESS) { slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, - "_cl5CheckDBVersion: invalid dbversion\n"); + "_cl5CheckDBVersion: upgrade %s -> %s failed\n", + dbVersion, clVersion); rc = CL5_BAD_DBVERSION; } } - } - +bailout: return rc; } -static int _cl5ReadDBVersion (const char *dir, char *clVersion) +static int _cl5ReadDBVersion (const char *dir, char *clVersion, int buflen) { int rc; PRFileDesc *file; @@ -3416,7 +3546,7 @@ static int _cl5ReadDBVersion (const char *dir, char *clVersion) { if (clVersion) { - strcpy(clVersion, tok); + PL_strncpyz(clVersion, tok, buflen); } } @@ -3442,7 +3572,8 @@ static int _cl5WriteDBVersion () PR_snprintf (fName, MAXPATHLEN, "%s/%s", s_cl5Desc.dbDir, VERSION_FILE); - file = PR_Open (fName, PR_WRONLY | PR_CREATE_FILE, s_cl5Desc.dbConfig.fileMode); + file = PR_Open (fName, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, + s_cl5Desc.dbConfig.fileMode); if (file == NULL) { slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl, @@ -3452,10 +3583,10 @@ static int _cl5WriteDBVersion () } /* write changelog version */ - PR_snprintf (clVersion, VERSION_SIZE, "%s/%s/%s\n", CL5_TYPE, REPL_PLUGIN_NAME, - CHANGELOG_DB_VERSION); + PR_snprintf (clVersion, VERSION_SIZE, "%s/%d.%d/%s\n", + BDB_IMPL, DB_VERSION_MAJOR, DB_VERSION_MINOR, BDB_REPLPLUGIN); - len = strlen (clVersion); + len = strlen(clVersion); size = slapi_write_buffer (file, clVersion, len); if (size != len) { @@ -3492,15 +3623,26 @@ static int _cl5CheckGuardian () } else { - PR_snprintf (plVersion, VERSION_SIZE, "%s/%s/%s", CL5_TYPE, REPL_PLUGIN_NAME, - CHANGELOG_DB_VERSION); + PR_snprintf (plVersion, VERSION_SIZE, "%s/%d.%d/%s\n", + BDB_IMPL, DB_VERSION_MAJOR, DB_VERSION_MINOR, BDB_REPLPLUGIN); rc = _cl5ReadGuardian (dbVersion); if (rc != CL5_SUCCESS || strcasecmp (plVersion, dbVersion) != 0) { - slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl, - "_cl5CheckGuardian: missing or invalid guardian file\n"); - return (CL5_BAD_FORMAT); + 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 */ @@ -3534,8 +3676,8 @@ static int _cl5WriteGuardian () return CL5_SYSTEM_ERROR; } - PR_snprintf (version, VERSION_SIZE, "%s/%s/%s\n", CL5_TYPE, REPL_PLUGIN_NAME, - CHANGELOG_DB_VERSION); + 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); diff --git a/ldap/servers/plugins/replication/cl5_api.h b/ldap/servers/plugins/replication/cl5_api.h index 66cb0f47..db95f168 100644 --- a/ldap/servers/plugins/replication/cl5_api.h +++ b/ldap/servers/plugins/replication/cl5_api.h @@ -48,6 +48,10 @@ #include "repl5.h" #include "repl5_prot_private.h" +#define BDB_IMPL "bdb" /* changelog type */ +#define BDB_REPLPLUGIN "libreplication-plugin" /* This backend plugin */ + + #define CL5_TYPE "Changelog5" /* changelog type */ #define VERSION_SIZE 127 /* size of the buffer to hold changelog version */ #define CL5_DEFAULT_CONFIG -1 /* value that indicates to changelog to use default */ diff --git a/ldap/servers/plugins/replication/repl_shared.h b/ldap/servers/plugins/replication/repl_shared.h index 957fdc76..5cff8612 100644 --- a/ldap/servers/plugins/replication/repl_shared.h +++ b/ldap/servers/plugins/replication/repl_shared.h @@ -128,11 +128,8 @@ * a different version for the plugin itself and this particular version is only * used for the changelog database */ -/* - * Changed version from 2.0 to 3.0 when we switched from libdb33 to libdb41 - * noriko 20021203 - */ -#define CHANGELOG_DB_VERSION_PREV "3.0" +/* the current CHANGELOG_DB_VERSION: DB_VERSION_MAJOR"."DB_VERSION_MINOR" */ +/* this string is left for the backward compatibility */ #define CHANGELOG_DB_VERSION "4.0" extern char *repl_plugin_name; extern char *windows_repl_plugin_name; |
