From f0b5031f5dabeb084aaeb8210a29fbf7e479f6a6 Mon Sep 17 00:00:00 2001
From: Ludwig Krispenz <lkrispen@redhat.com>
Date: Tue, 23 Jan 2018 13:23:52 +0100
Subject: [PATCH 2/3] move cldb - upgrade legacy changelog files

---
 ldap/servers/plugins/replication/cl5.h           |   4 +-
 ldap/servers/plugins/replication/cl5_config.c    | 300 ++---------------------
 ldap/servers/plugins/replication/cl5_init.c      | 104 ++++++--
 ldap/servers/plugins/replication/repl5_init.c    |   9 +-
 ldap/servers/plugins/replication/repl5_plugins.c |   3 +-
 ldap/servers/plugins/replication/repl5_replica.c |   2 +-
 ldap/servers/slapd/back-ldbm/archive.c           |   1 -
 ldap/servers/slapd/back-ldbm/dblayer.c           |  23 ++
 ldap/servers/slapd/plugin.c                      |   4 +
 ldap/servers/slapd/slapi-plugin.h                |   4 +-
 10 files changed, 148 insertions(+), 306 deletions(-)

diff --git a/ldap/servers/plugins/replication/cl5.h b/ldap/servers/plugins/replication/cl5.h
index 2af57e3..4249d2b 100644
--- a/ldap/servers/plugins/replication/cl5.h
+++ b/ldap/servers/plugins/replication/cl5.h
@@ -31,7 +31,9 @@ typedef struct changelog5Config
     long trimInterval;
 } changelog5Config;
 
-/* initializes changelog*/
+/* upgrade changelog*/
+int changelog5_upgrade(void);
+/* initialize changelog*/
 int changelog5_init(void);
 /* cleanups changelog data */
 void changelog5_cleanup(void);
diff --git a/ldap/servers/plugins/replication/cl5_config.c b/ldap/servers/plugins/replication/cl5_config.c
index dc40b6c..749bcfe 100644
--- a/ldap/servers/plugins/replication/cl5_config.c
+++ b/ldap/servers/plugins/replication/cl5_config.c
@@ -109,12 +109,10 @@ changelog5_read_config(changelog5Config *config)
             /* Extract the config info from the changelog entry */
             changelog5_extract_config(entries[0], config);
         } else {
-            memset(config, 0, sizeof(*config));
-            rc = LDAP_SUCCESS;
+            rc = LDAP_NO_SUCH_OBJECT;
         }
     } else {
-        memset(config, 0, sizeof(*config));
-        rc = LDAP_SUCCESS;
+        rc = LDAP_NO_SUCH_OBJECT;
     }
 
     slapi_free_search_results_internal(pb);
@@ -148,87 +146,18 @@ changelog5_config_add(Slapi_PBlock *pb __attribute__((unused)),
                       char *returntext,
                       void *arg __attribute__((unused)))
 {
-    int rc;
-    changelog5Config config;
 
+    /* we no longer support a separate changelog configuration
+     * so we should return UNWILLING_TO_PERFORM, but to keep existing
+     * tests and scripts happy just make it a NOOP
+     */
     *returncode = LDAP_SUCCESS;
 
-    slapi_rwlock_wrlock(s_configLock);
-
-    /* we already have a configured changelog - don't need to do anything
-       since add operation will fail */
-    if (cl5GetState() == CL5_STATE_OPEN) {
-        *returncode = 1;
-        if (returntext) {
-            strcpy(returntext, "attempt to add changelog when it already exists");
-        }
-
-        slapi_log_err(SLAPI_LOG_NOTICE, repl_plugin_name_cl,
-                      "changelog5_config_add - Changelog already exist; "
-                      "request ignored\n");
-        goto done;
-    }
-
-    changelog5_extract_config(e, &config);
-    if (config.dir == NULL) {
-        *returncode = 1;
-        if (returntext) {
-            PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "NULL changelog directory");
-        }
-
-        slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl,
-                      "changelog5_config_add - NULL changelog directory\n");
-        goto done;
-    }
-
-    /* start the changelog */
-    rc = cl5Open(&config.dbconfig);
-    if (rc != CL5_SUCCESS) {
-        *returncode = 1;
-        if (returntext) {
-            PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Failed to start changelog; error - %d", rc);
-        }
-
-        slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl,
-                      "changelog5_config_add - Failed to start changelog\n");
-        goto done;
-    }
-
-    /* set trimming parameters */
-    rc = cl5ConfigTrimming(config.maxEntries, config.maxAge, config.compactInterval, config.trimInterval);
-    if (rc != CL5_SUCCESS) {
-        *returncode = 1;
-        if (returntext) {
-            PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "failed to configure changelog trimming; error - %d", rc);
-        }
-        slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl,
-                      "changelog5_config_add - Failed to configure changelog trimming\n");
-        goto done;
-    }
-
-    /* notify all the replicas that the changelog is configured
-       so that the can log dummy changes if necessary. */
-
-    /* the changelog entry is only used for trimmming config 
-    replica_enumerate_replicas(notify_replica, NULL);
-    */
-
-#ifdef TEST_CL5
-    testChangelog(TEST_ITERATION);
-#endif
-
-done:;
-    slapi_rwlock_unlock(s_configLock);
-    changelog5_config_done(&config);
-    if (*returncode == LDAP_SUCCESS) {
-        if (returntext) {
-            returntext[0] = '\0';
-        }
-
-        return SLAPI_DSE_CALLBACK_OK;
-    }
+    slapi_log_err(SLAPI_LOG_NOTICE, repl_plugin_name_cl,
+                  "changelog5_config_add - Separate changelog no longer supported; "
+                  "request ignored\n");
 
-    return SLAPI_DSE_CALLBACK_ERROR;
+    return SLAPI_DSE_CALLBACK_OK;
 }
 
 static int
@@ -239,211 +168,18 @@ changelog5_config_modify(Slapi_PBlock *pb,
                          char *returntext,
                          void *arg __attribute__((unused)))
 {
-    int rc = 0;
-    LDAPMod **mods;
-    int i;
-    changelog5Config config;
-    changelog5Config *originalConfig = NULL;
-    char *currentDir = NULL;
-
-    *returncode = LDAP_SUCCESS;
 
-    /* changelog must be open before its parameters can be modified */
-    if (cl5GetState() != CL5_STATE_OPEN) {
-        if (returntext) {
-            strcpy(returntext, "changelog is not configured");
-        }
-
-        slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl,
-                      "changelog5_config_modify - Changelog is not configured\n");
-        return SLAPI_DSE_CALLBACK_ERROR;
-    }
-
-    slapi_rwlock_wrlock(s_configLock);
-
-    /* changelog must be open before its parameters can be modified */
-    if (cl5GetState() != CL5_STATE_OPEN) {
-        *returncode = 1;
-        if (returntext) {
-            strcpy(returntext, "changelog is not configured");
-        }
-
-        slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl,
-                      "changelog5_config_modify - Changelog is not configured\n");
-        goto done;
-    }
-
-    /*
-     * Extract all the original configuration: This is needed to ensure that the configuration
-     * is trully reloaded. This was not needed before 091401 because the changelog configuration
-     * was always hardcoded (NULL was being passed to cl5Open). Now we need to ensure we pass to
-     * cl5Open the proper configuration...
+    /* we no longer support a separate changelog configuration
+     * so we should return UNWILLING_TO_PERFORM, but to keep existing
+     * tests and scripts happy just make it a NOOP
      */
-    changelog5_extract_config(e, &config);
-    originalConfig = changelog5_dup_config(&config);
-
-    /* Reset all the attributes that have been potentially modified by the current MODIFY operation */
-    slapi_ch_free_string(&config.dir);
-    config.dir = NULL;
-    config.maxEntries = CL5_NUM_IGNORE;
-    config.compactInterval = CL5_NUM_IGNORE;
-    slapi_ch_free_string(&config.maxAge);
-    config.maxAge = slapi_ch_strdup(CL5_STR_IGNORE);
-    config.trimInterval = CL5_NUM_IGNORE;
-
-    slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
-    for (i = 0; mods && mods[i] != NULL; i++) {
-        if (mods[i]->mod_op & LDAP_MOD_DELETE) {
-            /* We don't support deleting changelog attributes */
-        } else if (mods[i]->mod_values == NULL) {
-            *returncode = LDAP_UNWILLING_TO_PERFORM;
-            if (returntext) {
-                PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
-                                        "%s: no value provided",
-                                        mods[i]->mod_type ? mods[i]->mod_type : "<unknown attribute>");
-            }
-            goto done;
-        } else {
-            int j;
-            for (j = 0; ((mods[i]->mod_values[j]) && (LDAP_SUCCESS == rc)); j++) {
-                char *config_attr, *config_attr_value;
-                config_attr = (char *)mods[i]->mod_type;
-                config_attr_value = (char *)mods[i]->mod_bvalues[j]->bv_val;
-
-                if (slapi_attr_is_last_mod(config_attr)) {
-                    continue;
-                }
-
-                /* replace existing value */
-                if (strcasecmp(config_attr, CONFIG_CHANGELOG_DIR_ATTRIBUTE) == 0) {
-                    if (config_attr_value && config_attr_value[0] != '\0') {
-                        slapi_ch_free_string(&config.dir);
-                        config.dir = slapi_ch_strdup(config_attr_value);
-                        replace_bslash(config.dir);
-                    } else {
-                        *returncode = 1;
-                        if (returntext) {
-                            strcpy(returntext, "null changelog directory");
-                        }
-                        goto done;
-                    }
-                } else if (strcasecmp(config_attr, CONFIG_CHANGELOG_MAXENTRIES_ATTRIBUTE) == 0) {
-                    if (config_attr_value && config_attr_value[0] != '\0') {
-                        config.maxEntries = atoi(config_attr_value);
-                    } else {
-                        config.maxEntries = 0;
-                    }
-                } else if (strcasecmp(config_attr, CONFIG_CHANGELOG_MAXAGE_ATTRIBUTE) == 0) {
-                    if (slapi_is_duration_valid(config_attr_value)) {
-                        slapi_ch_free_string(&config.maxAge);
-                        config.maxAge = slapi_ch_strdup(config_attr_value);
-                    } else {
-                        if (returntext) {
-                            PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
-                                        "%s: invalid value \"%s\", %s must range from 0 to %lld or digit[sSmMhHdD]",
-                                        CONFIG_CHANGELOG_MAXAGE_ATTRIBUTE, config_attr_value ? config_attr_value : "null",
-                                        CONFIG_CHANGELOG_MAXAGE_ATTRIBUTE,
-                                        (long long int)LONG_MAX);
-                        }
-                        *returncode = LDAP_UNWILLING_TO_PERFORM;
-                        goto done;
-                    }
-                } else if (strcasecmp(config_attr, CONFIG_CHANGELOG_COMPACTDB_ATTRIBUTE) == 0) {
-                    if (slapi_is_duration_valid(config_attr_value)) {
-                        config.compactInterval = (long)slapi_parse_duration(config_attr_value);
-                    } else {
-                        if (returntext) {
-                            PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
-                                        "%s: invalid value \"%s\", %s must range from 0 to %lld or digit[sSmMhHdD]",
-                                        CONFIG_CHANGELOG_COMPACTDB_ATTRIBUTE, config_attr_value,
-                                        CONFIG_CHANGELOG_COMPACTDB_ATTRIBUTE,
-                                        (long long int)LONG_MAX);
-                        }
-                        *returncode = LDAP_UNWILLING_TO_PERFORM;
-                        goto done;
-                    }
-                } else if (strcasecmp(config_attr, CONFIG_CHANGELOG_TRIM_ATTRIBUTE) == 0) {
-                    if (slapi_is_duration_valid(config_attr_value)) {
-                        config.trimInterval = (long)slapi_parse_duration(config_attr_value);
-                    } else {
-                        if (returntext) {
-                            PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
-                                        "%s: invalid value \"%s\", %s must range from 0 to %lld or digit[sSmMhHdD]",
-                                        CONFIG_CHANGELOG_TRIM_ATTRIBUTE, config_attr_value,
-                                        CONFIG_CHANGELOG_TRIM_ATTRIBUTE,
-                                        (long long int)LONG_MAX);
-                        }
-                        *returncode = LDAP_UNWILLING_TO_PERFORM;
-                        goto done;
-                    }
-                } else if (strcasecmp(config_attr, CONFIG_CHANGELOG_SYMMETRIC_KEY) == 0) {
-                    slapi_ch_free_string(&config.symmetricKey);
-                    config.symmetricKey = slapi_ch_strdup(config_attr_value);
-                    /* Storing the encryption symmetric key */
-                    /* no need to change any changelog configuration */
-                    goto done;
-                } else {
-                    *returncode = LDAP_UNWILLING_TO_PERFORM;
-                    if (returntext) {
-                        PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
-                                    "Unwilling to apply %s mods while the server is running", config_attr);
-                    }
-                    goto done;
-                }
-            }
-        }
-    }
-    /* Undo the reset above for all the modifiable attributes that were not modified
-     * except config.dir */
-    if (config.maxEntries == CL5_NUM_IGNORE)
-        config.maxEntries = originalConfig->maxEntries;
-    if (config.compactInterval == CL5_NUM_IGNORE)
-        config.compactInterval = originalConfig->compactInterval;
-    if (config.trimInterval == CL5_NUM_IGNORE)
-        config.trimInterval = originalConfig->trimInterval;
-    if (strcmp(config.maxAge, CL5_STR_IGNORE) == 0) {
-        slapi_ch_free_string(&config.maxAge);
-        if (originalConfig->maxAge)
-            config.maxAge = slapi_ch_strdup(originalConfig->maxAge);
-    }
-
-
-    /* one of the changelog parameters is modified */
-    if (config.maxEntries != CL5_NUM_IGNORE ||
-        config.trimInterval != CL5_NUM_IGNORE ||
-        strcmp(config.maxAge, CL5_STR_IGNORE) != 0) {
-        rc = cl5ConfigTrimming(config.maxEntries, config.maxAge, config.compactInterval, config.trimInterval);
-        if (rc != CL5_SUCCESS) {
-            *returncode = 1;
-            if (returntext) {
-                PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "failed to configure changelog trimming; error - %d", rc);
-            }
-
-            slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl,
-                          "changelog5_config_modify - Failed to configure changelog trimming\n");
-            goto done;
-        }
-    }
-
-done:;
-    slapi_rwlock_unlock(s_configLock);
-
-    changelog5_config_done(&config);
-    changelog5_config_free(&originalConfig);
-
-    /* slapi_ch_free accepts NULL pointer */
-    slapi_ch_free((void **)&currentDir);
-
-    if (*returncode == LDAP_SUCCESS) {
-
-        if (returntext) {
-            returntext[0] = '\0';
-        }
+    *returncode = LDAP_SUCCESS;
 
-        return SLAPI_DSE_CALLBACK_OK;
-    }
+    slapi_log_err(SLAPI_LOG_NOTICE, repl_plugin_name_cl,
+                  "changelog5_config_modify - Separate changelog no longer supported; "
+                  "request ignored\n");
 
-    return SLAPI_DSE_CALLBACK_ERROR;
+    return SLAPI_DSE_CALLBACK_OK;
 }
 
 static int
diff --git a/ldap/servers/plugins/replication/cl5_init.c b/ldap/servers/plugins/replication/cl5_init.c
index 3fc8e39..ec60c74 100644
--- a/ldap/servers/plugins/replication/cl5_init.c
+++ b/ldap/servers/plugins/replication/cl5_init.c
@@ -20,12 +20,40 @@
 #include "cl5.h"
 #include "repl5.h"
 
-/* initializes changelog*/
+static int _cl5_upgrade_replica(Replica *replica, void *arg);
+static int _cl5_upgrade_removedir(char *path);
+
+/* upgrade changelog*/
+/* the changelog5 configuration maintained all changlog files in a separate directory
+ * now the changlog is part of the instance database.
+ * if this is the first startup with teh new version we will try to move the changelog files
+ * for each replica to the intstance database
+ */
+int
+changelog5_upgrade(void)
+{
+    int rc = 0;
+    changelog5Config config = {};
+
+    changelog5_read_config(&config);
+
+    if (config.dir == NULL) {
+        /* we do not have a valid legacy config, nothing to upgrade */
+        return rc;
+    }
+
+    replica_enumerate_replicas(_cl5_upgrade_replica, (void *)&config);
+
+    rc = _cl5_upgrade_removedir(config.dir);
+
+    return rc;
+}
+
 int
-changelog5_init()
+changelog5_init(void)
 {
     int rc;
-    changelog5Config config;
+    changelog5Config config = {0};
 
     rc = cl5Init();
     if (rc != CL5_SUCCESS) {
@@ -34,18 +62,6 @@ changelog5_init()
         return 1;
     }
 
-    /* read changelog configuration */
-    changelog5_config_init();
-    changelog5_read_config(&config);
-
-    if (config.dir == NULL) {
-        /* changelog is not configured - bail out */
-        /* Note: but still changelog needs to be initialized to allow it
-         * to configure after this point. (don't call cl5Cleanup) */
-        rc = 0; /* OK */
-        goto done;
-    }
-
     /* start changelog */
     rc = cl5Open(&config.dbconfig);
     if (rc != CL5_SUCCESS) {
@@ -83,3 +99,61 @@ changelog5_cleanup()
     /* cleanup config */
     changelog5_config_cleanup();
 }
+static int
+_cl5_upgrade_replica(Replica *replica, void *arg)
+{
+    int rc = 0;
+    changelog5Config *config = (changelog5Config *)arg;
+    const char *replGen = replica_get_generation (replica);
+    const char *replName = replica_get_name (replica);
+    char *oldFile = slapi_ch_smprintf("%s/%s_%s.db",
+                                       config->dir, replName, replGen);
+    if (PR_Access(oldFile, PR_ACCESS_EXISTS) == PR_SUCCESS) {
+        Slapi_Backend *be = slapi_be_select(replica_get_root(replica));
+        char *instancedir;
+        slapi_back_get_info(be, BACK_INFO_INSTANCE_DIR, (void **)&instancedir);
+        char *newFile = slapi_ch_smprintf("%s/changelog.db", instancedir);
+
+        rc = slapi_back_ctrl_info(be, BACK_INFO_DBENV_CLDB_UPGRADE, oldFile);
+        slapi_log_err(SLAPI_LOG_INFO, repl_plugin_name_cl,
+                      "_cl5_upgrade_replica: moving file (%s) to (%s) %s\n",
+                      oldFile, newFile, rc?"failed":"succeeded");
+    }
+
+    return rc;
+}
+static int
+_cl5_upgrade_removedir(char *path)
+{
+    /* this is duplicated from ldbm_delete_dirs, we unfortunately
+     * cannot access the backend functions
+     */
+    PRDir *dirhandle = NULL;
+    PRDirEntry *direntry = NULL;
+    char fullpath[MAXPATHLEN];
+    int rval = 0;
+    PRFileInfo64 info;
+
+    dirhandle = PR_OpenDir(path);
+    if (!dirhandle) {
+        PR_Delete(path);
+        return 0;
+    }
+
+    while (NULL != (direntry =
+                        PR_ReadDir(dirhandle, PR_SKIP_DOT | PR_SKIP_DOT_DOT))) {
+        if (!direntry->name)
+            break;
+
+        PR_snprintf(fullpath, MAXPATHLEN, "%s/%s", path, direntry->name);
+        rval = PR_GetFileInfo64(fullpath, &info);
+        if (PR_SUCCESS == rval) {
+            PR_Delete(fullpath);
+        }
+    }
+    PR_CloseDir(dirhandle);
+    /* remove the directory itself too */
+    rval += PR_RmDir(path);
+    return rval;
+}
+
diff --git a/ldap/servers/plugins/replication/repl5_init.c b/ldap/servers/plugins/replication/repl5_init.c
index 5badd7c..6afd0fe 100644
--- a/ldap/servers/plugins/replication/repl5_init.c
+++ b/ldap/servers/plugins/replication/repl5_init.c
@@ -387,7 +387,6 @@ multimaster_bepostop_init(Slapi_PBlock *pb)
         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_OPEN_FN, (void *)changelog5_init) != 0 ||
         slapi_pblock_set(pb, SLAPI_PLUGIN_BE_POST_BACKUP_FN, (void *)cl5DeleteRUV) != 0) {
         slapi_log_err(SLAPI_LOG_PLUGIN, repl_plugin_name, "multimaster_bepostop_init - Failed\n");
         rc = -1;
@@ -408,7 +407,6 @@ multimaster_betxn_bepostop_init(Slapi_PBlock *pb)
 
     if (slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01) ||
         slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&multimasterbepostopdesc) ||
-        slapi_pblock_set(pb, SLAPI_PLUGIN_BE_POST_OPEN_FN, (void *)changelog5_init) ||
         slapi_pblock_set(pb, SLAPI_PLUGIN_BE_POST_BACKUP_FN, (void *)cl5DeleteRUV)) {
         slapi_log_err(SLAPI_LOG_PLUGIN, repl_plugin_name, "multimaster_betxn_bepostop_init - Failed\n");
         rc = -1;
@@ -797,7 +795,12 @@ multimaster_start(Slapi_PBlock *pb)
         /* create replicas */
         multimaster_mtnode_construct_replicas();
 
-        /* Initialise the 5.0 Changelog */
+        /* Upgrade the 5.0 Changelog if it still exists */
+        rc = changelog5_upgrade();
+        if (rc != 0)
+            goto out;
+
+        /* perform initial changelog setup */
         rc = changelog5_init();
         if (rc != 0)
             goto out;
diff --git a/ldap/servers/plugins/replication/repl5_plugins.c b/ldap/servers/plugins/replication/repl5_plugins.c
index 79d4c9b..57129b1 100644
--- a/ldap/servers/plugins/replication/repl5_plugins.c
+++ b/ldap/servers/plugins/replication/repl5_plugins.c
@@ -1001,8 +1001,7 @@ write_changelog_and_ruv(Slapi_PBlock *pb)
 
     replica_check_release_timeout(r, pb);
 
-    if (replica_is_flag_set(r, REPLICA_LOG_CHANGES) &&
-        (cl5GetState() == CL5_STATE_OPEN)) {
+    if (replica_is_flag_set(r, REPLICA_LOG_CHANGES)) {
         supplier_operation_extension *opext = NULL;
         cldb_Handle *cldb;
 
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index b5153dd..2b49596 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -202,7 +202,7 @@ replica_new_from_entry(Slapi_Entry *e, char *errortext, PRBool is_add_operation)
         goto done;
     }
 
-    if (r->repl_flags & REPLICA_LOG_CHANGES) {
+    if (is_add_operation && (r->repl_flags & REPLICA_LOG_CHANGES)) {
         /* Init changelog db file */
         nCL_SetReplicaDB(r, NULL);
     }
diff --git a/ldap/servers/slapd/back-ldbm/archive.c b/ldap/servers/slapd/back-ldbm/archive.c
index 4a9ce3d..8bf2e8f 100644
--- a/ldap/servers/slapd/back-ldbm/archive.c
+++ b/ldap/servers/slapd/back-ldbm/archive.c
@@ -231,7 +231,6 @@ ldbm_back_archive2ldbm(Slapi_PBlock *pb)
             }
         }
         /* 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);
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
index 2163695..204634b 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
@@ -7177,6 +7177,15 @@ ldbm_back_get_info(Slapi_Backend *be, int cmd, void **info)
         }
         break;
     }
+    case BACK_INFO_INSTANCE_DIR: {
+        struct ldbminfo *li = (struct ldbminfo *)be->be_database->plg_private;
+        if (li) {
+            ldbm_instance *inst = (ldbm_instance *)be->be_instance_info;
+            *(char **)info = dblayer_get_full_inst_dir(li, inst, NULL, 0);
+            rc = 0;
+        }
+        break;
+    }
     case BACK_INFO_LOG_DIRECTORY: {
         struct ldbminfo *li = (struct ldbminfo *)be->be_database->plg_private;
         if (li) {
@@ -7240,6 +7249,20 @@ ldbm_back_ctrl_info(Slapi_Backend *be, int cmd, void *info)
                                       &(crypt_value->out));
         break;
     }
+    case BACK_INFO_DBENV_CLDB_UPGRADE: {
+        struct ldbminfo *li = (struct ldbminfo *)be->be_database->plg_private;
+        char *oldFile = (char *)info;
+        if (li) {
+            dblayer_private *prv = (dblayer_private *)li->li_dblayer_private;
+            if (prv && prv->dblayer_env && prv->dblayer_env->dblayer_DB_ENV) {
+                char *instancedir;
+                slapi_back_get_info(be, BACK_INFO_INSTANCE_DIR, (void **)&instancedir);
+                char *newFile = slapi_ch_smprintf("%s/changelog.db", instancedir);
+                rc = prv->dblayer_env->dblayer_DB_ENV->dbrename(prv->dblayer_env->dblayer_DB_ENV, 0, oldFile, 0, newFile, 0);
+            }
+        }
+        break;
+    }
     default:
         break;
     }
diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c
index 2db3c7f..b175f74 100644
--- a/ldap/servers/slapd/plugin.c
+++ b/ldap/servers/slapd/plugin.c
@@ -1734,6 +1734,10 @@ plugin_dependency_startall(int argc, char **argv, char *errmsg __attribute__((un
                      * access to the real plugin for registering callbacks, tasks, etc.
                      */
                     slapi_pblock_set(config[plugin_index].pb, SLAPI_PLUGIN, config[plugin_index].plugin);
+
+                        slapi_log_err(SLAPI_LOG_ERR, "plugin_dependency_startall",
+                                      "Starting %s plugin %s at index %d\n",
+                                      config[plugin_index].type, config[plugin_index].name, plugin_index);
                     ret = plugin_call_one(config[plugin_index].plugin, operation, config[plugin_index].pb);
 
                     /* We used to call pblock done here, bet we try to restart
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index c4b8c1c..0559af2 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -7758,12 +7758,14 @@ enum
     BACK_INFO_DBENV_CLDB,          /* Get the changelog */
     BACK_INFO_DBENV_CLDB_REMOVE,   /* Remove the changelog */
     BACK_INFO_DBENV_CLDB_RESET,    /* Recreate the changelog */
+    BACK_INFO_DBENV_CLDB_UPGRADE,  /* Move an old cl file to the instance database */
     BACK_INFO_INDEXPAGESIZE,       /* Get the index page size */
     BACK_INFO_DBENV_OPENFLAGS,     /* Get the dbenv openflags */
     BACK_INFO_CRYPT_INIT,          /* Ctrl: clcrypt_init */
     BACK_INFO_CRYPT_ENCRYPT_VALUE, /* Ctrl: clcrypt_encrypt_value */
     BACK_INFO_CRYPT_DECRYPT_VALUE, /* Ctrl: clcrypt_decrypt_value */
-    BACK_INFO_DIRECTORY,           /* Get the directory path */
+    BACK_INFO_DIRECTORY,           /* Get the db directory path */
+    BACK_INFO_INSTANCE_DIR,        /* Get the path to an instance */
     BACK_INFO_LOG_DIRECTORY,       /* Get the txn log directory */
     BACK_INFO_IS_ENTRYRDN          /* Get the flag for entryrdn */
 };
-- 
2.9.5

