From 59266365eda8130abf6901263efae4c87586376a Mon Sep 17 00:00:00 2001 From: Thierry Bordaz 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