From 59266365eda8130abf6901263efae4c87586376a Mon Sep 17 00:00:00 2001
From: Thierry Bordaz <tbordaz@redhat.com>
Date: Mon, 28 Jun 2021 16:40:15 +0200
Subject: [PATCH] Issue 4814 - _cl5_get_tod_expiration may crash at startup
Bug description:
This bug exist only in 1.4.3 branch
In 1.4.3, CL open as a separated database so
compaction mechanism is started along a CL
mechanism (CL trimming).
The problem is that the configuration of the CL
compaction is done after the compaction mechanism
(is started). Depending on thread scheduling it
crashes
Fix description:
Make sure configuration of compaction thread is
taken into account (cl5ConfigSetCompaction) before
the compaction thread starts (cl5open)
relates: https://github.com/389ds/389-ds-base/issues/4814
Reviewed by: Mark Reynolds, Simon Pichugin (thanks !)
Platforms tested: 8.5
---
ldap/servers/plugins/replication/cl5_api.c | 24 ++++++++++++-------
ldap/servers/plugins/replication/cl5_api.h | 10 +++++++-
ldap/servers/plugins/replication/cl5_config.c | 8 +++++--
ldap/servers/plugins/replication/cl5_init.c | 4 +++-
ldap/servers/plugins/replication/cl5_test.c | 2 +-
.../servers/plugins/replication/repl_shared.h | 2 +-
6 files changed, 35 insertions(+), 15 deletions(-)
diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c
index 4c5077b48..954b6b9e3 100644
--- a/ldap/servers/plugins/replication/cl5_api.c
+++ b/ldap/servers/plugins/replication/cl5_api.c
@@ -1016,6 +1016,20 @@ cl5GetState()
return s_cl5Desc.dbState;
}
+void
+cl5ConfigSetCompaction(int compactInterval, char *compactTime)
+{
+
+ if (compactInterval != CL5_NUM_IGNORE) {
+ s_cl5Desc.dbTrim.compactInterval = compactInterval;
+ }
+
+ if (strcmp(compactTime, CL5_STR_IGNORE) != 0) {
+ s_cl5Desc.dbTrim.compactTime = slapi_ch_strdup(compactTime);
+ }
+
+}
+
/* Name: cl5ConfigTrimming
Description: sets changelog trimming parameters; changelog must be open.
Parameters: maxEntries - maximum number of entries in the chnagelog (in all files);
@@ -1026,7 +1040,7 @@ cl5GetState()
CL5_BAD_STATE if changelog is not open
*/
int
-cl5ConfigTrimming(int maxEntries, const char *maxAge, int compactInterval, char *compactTime, int trimInterval)
+cl5ConfigTrimming(int maxEntries, const char *maxAge, int trimInterval)
{
if (s_cl5Desc.dbState == CL5_STATE_NONE) {
slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl,
@@ -1058,14 +1072,6 @@ cl5ConfigTrimming(int maxEntries, const char *maxAge, int compactInterval, char
s_cl5Desc.dbTrim.maxEntries = maxEntries;
}
- if (compactInterval != CL5_NUM_IGNORE) {
- s_cl5Desc.dbTrim.compactInterval = compactInterval;
- }
-
- if (strcmp(compactTime, CL5_STR_IGNORE) != 0) {
- s_cl5Desc.dbTrim.compactTime = slapi_ch_strdup(compactTime);
- }
-
if (trimInterval != CL5_NUM_IGNORE) {
s_cl5Desc.dbTrim.trimInterval = trimInterval;
}
diff --git a/ldap/servers/plugins/replication/cl5_api.h b/ldap/servers/plugins/replication/cl5_api.h
index 11db771f2..6aa48aec4 100644
--- a/ldap/servers/plugins/replication/cl5_api.h
+++ b/ldap/servers/plugins/replication/cl5_api.h
@@ -227,6 +227,14 @@ int cl5ImportLDIF(const char *clDir, const char *ldifFile, Replica **replicas);
int cl5GetState(void);
+/* Name: cl5ConfigSetCompaction
+ * Description: sets the database compaction parameters
+ * Parameters: compactInterval - Interval for compaction default is 30days
+ * compactTime - Compact time default is 23:59
+ * Return: void
+ */
+void cl5ConfigSetCompaction(int compactInterval, char *compactTime);
+
/* Name: cl5ConfigTrimming
Description: sets changelog trimming parameters
Parameters: maxEntries - maximum number of entries in the log;
@@ -236,7 +244,7 @@ int cl5GetState(void);
Return: CL5_SUCCESS if successful;
CL5_BAD_STATE if changelog has not been open
*/
-int cl5ConfigTrimming(int maxEntries, const char *maxAge, int compactInterval, char *compactTime, int trimInterval);
+int cl5ConfigTrimming(int maxEntries, const char *maxAge, int trimInterval);
void cl5DestroyIterator(void *iterator);
diff --git a/ldap/servers/plugins/replication/cl5_config.c b/ldap/servers/plugins/replication/cl5_config.c
index b32686788..a43534c9b 100644
--- a/ldap/servers/plugins/replication/cl5_config.c
+++ b/ldap/servers/plugins/replication/cl5_config.c
@@ -197,6 +197,8 @@ changelog5_config_add(Slapi_PBlock *pb __attribute__((unused)),
goto done;
}
+ /* Set compaction parameters */
+ cl5ConfigSetCompaction(config.compactInterval, config.compactTime);
/* start the changelog */
rc = cl5Open(config.dir, &config.dbconfig);
@@ -212,7 +214,7 @@ changelog5_config_add(Slapi_PBlock *pb __attribute__((unused)),
}
/* set trimming parameters */
- rc = cl5ConfigTrimming(config.maxEntries, config.maxAge, config.compactInterval, config.compactTime, config.trimInterval);
+ rc = cl5ConfigTrimming(config.maxEntries, config.maxAge, config.trimInterval);
if (rc != CL5_SUCCESS) {
*returncode = 1;
if (returntext) {
@@ -548,6 +550,8 @@ changelog5_config_modify(Slapi_PBlock *pb,
slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl,
"changelog5_config_modify - Deleted the changelog at %s\n", currentDir);
}
+ /* Set compaction parameters */
+ cl5ConfigSetCompaction(config.compactInterval, config.compactTime);
rc = cl5Open(config.dir, &config.dbconfig);
if (rc != CL5_SUCCESS) {
@@ -575,7 +579,7 @@ changelog5_config_modify(Slapi_PBlock *pb,
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.compactTime, config.trimInterval);
+ rc = cl5ConfigTrimming(config.maxEntries, config.maxAge, config.trimInterval);
if (rc != CL5_SUCCESS) {
*returncode = 1;
if (returntext) {
diff --git a/ldap/servers/plugins/replication/cl5_init.c b/ldap/servers/plugins/replication/cl5_init.c
index 251859714..567e0274c 100644
--- a/ldap/servers/plugins/replication/cl5_init.c
+++ b/ldap/servers/plugins/replication/cl5_init.c
@@ -45,6 +45,8 @@ changelog5_init()
rc = 0; /* OK */
goto done;
}
+ /* Set compaction parameters */
+ cl5ConfigSetCompaction(config.compactInterval, config.compactTime);
/* start changelog */
rc = cl5Open(config.dir, &config.dbconfig);
@@ -57,7 +59,7 @@ changelog5_init()
}
/* set trimming parameters */
- rc = cl5ConfigTrimming(config.maxEntries, config.maxAge, config.compactInterval, config.compactTime, config.trimInterval);
+ rc = cl5ConfigTrimming(config.maxEntries, config.maxAge, config.trimInterval);
if (rc != CL5_SUCCESS) {
slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl,
"changelog5_init: failed to configure changelog trimming\n");
diff --git a/ldap/servers/plugins/replication/cl5_test.c b/ldap/servers/plugins/replication/cl5_test.c
index d6656653c..efb8c543a 100644
--- a/ldap/servers/plugins/replication/cl5_test.c
+++ b/ldap/servers/plugins/replication/cl5_test.c
@@ -281,7 +281,7 @@ testTrimming()
rc = populateChangelog(300, NULL);
if (rc == 0)
- rc = cl5ConfigTrimming(300, "1d", CHANGELOGDB_COMPACT_INTERVAL, CHANGELOGDB_TRIM_INTERVAL);
+ rc = cl5ConfigTrimming(300, "1d", CHANGELOGDB_TRIM_INTERVAL);
interval = PR_SecondsToInterval(300); /* 5 min is default trimming interval */
slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl,
diff --git a/ldap/servers/plugins/replication/repl_shared.h b/ldap/servers/plugins/replication/repl_shared.h
index 6708e12f7..b59b2bd27 100644
--- a/ldap/servers/plugins/replication/repl_shared.h
+++ b/ldap/servers/plugins/replication/repl_shared.h
@@ -26,7 +26,7 @@
#define CHANGELOGDB_TRIM_INTERVAL 300 /* 5 minutes */
#define CHANGELOGDB_COMPACT_INTERVAL 2592000 /* 30 days */
-#define CHANGELOGDB_COMPACT_TIME "23:55" /* 30 days */
+#define CHANGELOGDB_COMPACT_TIME "23:59" /* around midnight */
#define CONFIG_CHANGELOG_DIR_ATTRIBUTE "nsslapd-changelogdir"
#define CONFIG_CHANGELOG_MAXENTRIES_ATTRIBUTE "nsslapd-changelogmaxentries"
--
2.31.1