|
|
47a30d |
From 9a8ee0954699da05501ded2900a834584346ef85 Mon Sep 17 00:00:00 2001
|
|
|
47a30d |
From: Thierry Bordaz <tbordaz@redhat.com>
|
|
|
47a30d |
Date: Mon, 25 Nov 2019 10:59:44 +0100
|
|
|
47a30d |
Subject: [PATCH] Ticket 50736 - RetroCL trimming may crash at shutdown if
|
|
|
47a30d |
trimming configuration is invalid
|
|
|
47a30d |
|
|
|
47a30d |
Bug Description:
|
|
|
47a30d |
If config of retroCL trimming contains invalid value for trim-interval
|
|
|
47a30d |
and/or maxage, then the trimming initialization is skipped.
|
|
|
47a30d |
In such case the trimming structures are not allocated and if they
|
|
|
47a30d |
are freed at shutdown it triggers a crash
|
|
|
47a30d |
|
|
|
47a30d |
Fix Description:
|
|
|
47a30d |
When trimming mechanism is stopped (at shutdown) check that
|
|
|
47a30d |
it was successfully initialized before freeing the structs
|
|
|
47a30d |
|
|
|
47a30d |
https://pagure.io/389-ds-base/issue/50736
|
|
|
47a30d |
|
|
|
47a30d |
Reviewed by: Mark Reynolds
|
|
|
47a30d |
|
|
|
47a30d |
Platforms tested: F30
|
|
|
47a30d |
|
|
|
47a30d |
Flag Day: no
|
|
|
47a30d |
|
|
|
47a30d |
Doc impact: no
|
|
|
47a30d |
---
|
|
|
47a30d |
.../suites/replication/changelog_test.py | 185 ++++++++++++++++++
|
|
|
47a30d |
ldap/servers/plugins/retrocl/retrocl_trim.c | 17 +-
|
|
|
47a30d |
2 files changed, 196 insertions(+), 6 deletions(-)
|
|
|
47a30d |
|
|
|
47a30d |
diff --git a/dirsrvtests/tests/suites/replication/changelog_test.py b/dirsrvtests/tests/suites/replication/changelog_test.py
|
|
|
47a30d |
index 0b6b886f3..0d3e85bb2 100755
|
|
|
47a30d |
--- a/dirsrvtests/tests/suites/replication/changelog_test.py
|
|
|
47a30d |
+++ b/dirsrvtests/tests/suites/replication/changelog_test.py
|
|
|
47a30d |
@@ -16,6 +16,12 @@ from lib389.replica import Replicas
|
|
|
47a30d |
from lib389.idm.user import UserAccounts
|
|
|
47a30d |
from lib389.topologies import topology_m2 as topo
|
|
|
47a30d |
from lib389._constants import *
|
|
|
47a30d |
+from lib389.plugins import RetroChangelogPlugin
|
|
|
47a30d |
+from lib389.dseldif import DSEldif
|
|
|
47a30d |
+from lib389.tasks import *
|
|
|
47a30d |
+from lib389.utils import *
|
|
|
47a30d |
+
|
|
|
47a30d |
+pytestmark = pytest.mark.tier1
|
|
|
47a30d |
|
|
|
47a30d |
TEST_ENTRY_NAME = 'replusr'
|
|
|
47a30d |
NEW_RDN_NAME = 'cl5usr'
|
|
|
47a30d |
@@ -235,6 +241,185 @@ def test_verify_changelog_offline_backup(topo):
|
|
|
47a30d |
_check_changelog_ldif(topo, changelog_ldif)
|
|
|
47a30d |
|
|
|
47a30d |
|
|
|
47a30d |
+@pytest.mark.ds47669
|
|
|
47a30d |
+def test_changelog_maxage(topo, changelog_init):
|
|
|
47a30d |
+ """Check nsslapd-changelog max age values
|
|
|
47a30d |
+
|
|
|
47a30d |
+ :id: d284ff27-03b2-412c-ac74-ac4f2d2fae3b
|
|
|
47a30d |
+ :setup: Replication with two master, change nsslapd-changelogdir to
|
|
|
47a30d |
+ '/var/lib/dirsrv/slapd-master1/changelog' and
|
|
|
47a30d |
+ set cn=Retro Changelog Plugin,cn=plugins,cn=config to 'on'
|
|
|
47a30d |
+ :steps:
|
|
|
47a30d |
+ 1. Set nsslapd-changelogmaxage in cn=changelog5,cn=config to values - '12345','10s','30M','12h','2D','4w'
|
|
|
47a30d |
+ 2. Set nsslapd-changelogmaxage in cn=changelog5,cn=config to values - '-123','xyz'
|
|
|
47a30d |
+
|
|
|
47a30d |
+ :expectedresults:
|
|
|
47a30d |
+ 1. Operation should be successful
|
|
|
47a30d |
+ 2. Operation should be unsuccessful
|
|
|
47a30d |
+ """
|
|
|
47a30d |
+ log.info('1. Test nsslapd-changelogmaxage in cn=changelog5,cn=config')
|
|
|
47a30d |
+
|
|
|
47a30d |
+ # bind as directory manager
|
|
|
47a30d |
+ topo.ms["master1"].log.info("Bind as %s" % DN_DM)
|
|
|
47a30d |
+ topo.ms["master1"].simple_bind_s(DN_DM, PASSWORD)
|
|
|
47a30d |
+
|
|
|
47a30d |
+ add_and_check(topo, CHANGELOG, MAXAGE, '12345', True)
|
|
|
47a30d |
+ add_and_check(topo, CHANGELOG, MAXAGE, '10s', True)
|
|
|
47a30d |
+ add_and_check(topo, CHANGELOG, MAXAGE, '30M', True)
|
|
|
47a30d |
+ add_and_check(topo, CHANGELOG, MAXAGE, '12h', True)
|
|
|
47a30d |
+ add_and_check(topo, CHANGELOG, MAXAGE, '2D', True)
|
|
|
47a30d |
+ add_and_check(topo, CHANGELOG, MAXAGE, '4w', True)
|
|
|
47a30d |
+ add_and_check(topo, CHANGELOG, MAXAGE, '-123', False)
|
|
|
47a30d |
+ add_and_check(topo, CHANGELOG, MAXAGE, 'xyz', False)
|
|
|
47a30d |
+
|
|
|
47a30d |
+
|
|
|
47a30d |
+@pytest.mark.ds47669
|
|
|
47a30d |
+def test_ticket47669_changelog_triminterval(topo, changelog_init):
|
|
|
47a30d |
+ """Check nsslapd-changelog triminterval values
|
|
|
47a30d |
+
|
|
|
47a30d |
+ :id: 8f850c37-7e7c-49dd-a4e0-9344638616d6
|
|
|
47a30d |
+ :setup: Replication with two master, change nsslapd-changelogdir to
|
|
|
47a30d |
+ '/var/lib/dirsrv/slapd-master1/changelog' and
|
|
|
47a30d |
+ set cn=Retro Changelog Plugin,cn=plugins,cn=config to 'on'
|
|
|
47a30d |
+ :steps:
|
|
|
47a30d |
+ 1. Set nsslapd-changelogtrim-interval in cn=changelog5,cn=config to values -
|
|
|
47a30d |
+ '12345','10s','30M','12h','2D','4w'
|
|
|
47a30d |
+ 2. Set nsslapd-changelogtrim-interval in cn=changelog5,cn=config to values - '-123','xyz'
|
|
|
47a30d |
+
|
|
|
47a30d |
+ :expectedresults:
|
|
|
47a30d |
+ 1. Operation should be successful
|
|
|
47a30d |
+ 2. Operation should be unsuccessful
|
|
|
47a30d |
+ """
|
|
|
47a30d |
+ log.info('2. Test nsslapd-changelogtrim-interval in cn=changelog5,cn=config')
|
|
|
47a30d |
+
|
|
|
47a30d |
+ # bind as directory manager
|
|
|
47a30d |
+ topo.ms["master1"].log.info("Bind as %s" % DN_DM)
|
|
|
47a30d |
+ topo.ms["master1"].simple_bind_s(DN_DM, PASSWORD)
|
|
|
47a30d |
+
|
|
|
47a30d |
+ add_and_check(topo, CHANGELOG, TRIMINTERVAL, '12345', True)
|
|
|
47a30d |
+ add_and_check(topo, CHANGELOG, TRIMINTERVAL, '10s', True)
|
|
|
47a30d |
+ add_and_check(topo, CHANGELOG, TRIMINTERVAL, '30M', True)
|
|
|
47a30d |
+ add_and_check(topo, CHANGELOG, TRIMINTERVAL, '12h', True)
|
|
|
47a30d |
+ add_and_check(topo, CHANGELOG, TRIMINTERVAL, '2D', True)
|
|
|
47a30d |
+ add_and_check(topo, CHANGELOG, TRIMINTERVAL, '4w', True)
|
|
|
47a30d |
+ add_and_check(topo, CHANGELOG, TRIMINTERVAL, '-123', False)
|
|
|
47a30d |
+ add_and_check(topo, CHANGELOG, TRIMINTERVAL, 'xyz', False)
|
|
|
47a30d |
+
|
|
|
47a30d |
+
|
|
|
47a30d |
+@pytest.mark.ds47669
|
|
|
47a30d |
+def test_changelog_compactdbinterval(topo, changelog_init):
|
|
|
47a30d |
+ """Check nsslapd-changelog compactdbinterval values
|
|
|
47a30d |
+
|
|
|
47a30d |
+ :id: 0f4b3118-9dfa-4c2a-945c-72847b42a48c
|
|
|
47a30d |
+ :setup: Replication with two master, change nsslapd-changelogdir to
|
|
|
47a30d |
+ '/var/lib/dirsrv/slapd-master1/changelog' and
|
|
|
47a30d |
+ set cn=Retro Changelog Plugin,cn=plugins,cn=config to 'on'
|
|
|
47a30d |
+ :steps:
|
|
|
47a30d |
+ 1. Set nsslapd-changelogcompactdb-interval in cn=changelog5,cn=config to values -
|
|
|
47a30d |
+ '12345','10s','30M','12h','2D','4w'
|
|
|
47a30d |
+ 2. Set nsslapd-changelogcompactdb-interval in cn=changelog5,cn=config to values -
|
|
|
47a30d |
+ '-123','xyz'
|
|
|
47a30d |
+
|
|
|
47a30d |
+ :expectedresults:
|
|
|
47a30d |
+ 1. Operation should be successful
|
|
|
47a30d |
+ 2. Operation should be unsuccessful
|
|
|
47a30d |
+ """
|
|
|
47a30d |
+ log.info('3. Test nsslapd-changelogcompactdb-interval in cn=changelog5,cn=config')
|
|
|
47a30d |
+
|
|
|
47a30d |
+ # bind as directory manager
|
|
|
47a30d |
+ topo.ms["master1"].log.info("Bind as %s" % DN_DM)
|
|
|
47a30d |
+ topo.ms["master1"].simple_bind_s(DN_DM, PASSWORD)
|
|
|
47a30d |
+
|
|
|
47a30d |
+ add_and_check(topo, CHANGELOG, COMPACTDBINTERVAL, '12345', True)
|
|
|
47a30d |
+ add_and_check(topo, CHANGELOG, COMPACTDBINTERVAL, '10s', True)
|
|
|
47a30d |
+ add_and_check(topo, CHANGELOG, COMPACTDBINTERVAL, '30M', True)
|
|
|
47a30d |
+ add_and_check(topo, CHANGELOG, COMPACTDBINTERVAL, '12h', True)
|
|
|
47a30d |
+ add_and_check(topo, CHANGELOG, COMPACTDBINTERVAL, '2D', True)
|
|
|
47a30d |
+ add_and_check(topo, CHANGELOG, COMPACTDBINTERVAL, '4w', True)
|
|
|
47a30d |
+ add_and_check(topo, CHANGELOG, COMPACTDBINTERVAL, '-123', False)
|
|
|
47a30d |
+ add_and_check(topo, CHANGELOG, COMPACTDBINTERVAL, 'xyz', False)
|
|
|
47a30d |
+
|
|
|
47a30d |
+
|
|
|
47a30d |
+@pytest.mark.ds47669
|
|
|
47a30d |
+def test_retrochangelog_maxage(topo, changelog_init):
|
|
|
47a30d |
+ """Check nsslapd-retrochangelog max age values
|
|
|
47a30d |
+
|
|
|
47a30d |
+ :id: 0cb84d81-3e86-4dbf-84a2-66aefd8281db
|
|
|
47a30d |
+ :setup: Replication with two master, change nsslapd-changelogdir to
|
|
|
47a30d |
+ '/var/lib/dirsrv/slapd-master1/changelog' and
|
|
|
47a30d |
+ set cn=Retro Changelog Plugin,cn=plugins,cn=config to 'on'
|
|
|
47a30d |
+ :steps:
|
|
|
47a30d |
+ 1. Set nsslapd-changelogmaxage in cn=Retro Changelog Plugin,cn=plugins,cn=config to values -
|
|
|
47a30d |
+ '12345','10s','30M','12h','2D','4w'
|
|
|
47a30d |
+ 2. Set nsslapd-changelogmaxage in cn=Retro Changelog Plugin,cn=plugins,cn=config to values -
|
|
|
47a30d |
+ '-123','xyz'
|
|
|
47a30d |
+
|
|
|
47a30d |
+ :expectedresults:
|
|
|
47a30d |
+ 1. Operation should be successful
|
|
|
47a30d |
+ 2. Operation should be unsuccessful
|
|
|
47a30d |
+ """
|
|
|
47a30d |
+ log.info('4. Test nsslapd-changelogmaxage in cn=Retro Changelog Plugin,cn=plugins,cn=config')
|
|
|
47a30d |
+
|
|
|
47a30d |
+ # bind as directory manager
|
|
|
47a30d |
+ topo.ms["master1"].log.info("Bind as %s" % DN_DM)
|
|
|
47a30d |
+ topo.ms["master1"].simple_bind_s(DN_DM, PASSWORD)
|
|
|
47a30d |
+
|
|
|
47a30d |
+ add_and_check(topo, RETROCHANGELOG, MAXAGE, '12345', True)
|
|
|
47a30d |
+ add_and_check(topo, RETROCHANGELOG, MAXAGE, '10s', True)
|
|
|
47a30d |
+ add_and_check(topo, RETROCHANGELOG, MAXAGE, '30M', True)
|
|
|
47a30d |
+ add_and_check(topo, RETROCHANGELOG, MAXAGE, '12h', True)
|
|
|
47a30d |
+ add_and_check(topo, RETROCHANGELOG, MAXAGE, '2D', True)
|
|
|
47a30d |
+ add_and_check(topo, RETROCHANGELOG, MAXAGE, '4w', True)
|
|
|
47a30d |
+ add_and_check(topo, RETROCHANGELOG, MAXAGE, '-123', False)
|
|
|
47a30d |
+ add_and_check(topo, RETROCHANGELOG, MAXAGE, 'xyz', False)
|
|
|
47a30d |
+
|
|
|
47a30d |
+ topo.ms["master1"].log.info("ticket47669 was successfully verified.")
|
|
|
47a30d |
+
|
|
|
47a30d |
+@pytest.mark.ds50736
|
|
|
47a30d |
+def test_retrochangelog_trimming_crash(topo, changelog_init):
|
|
|
47a30d |
+ """Check that when retroCL nsslapd-retrocthangelog contains invalid
|
|
|
47a30d |
+ value, then the instance does not crash at shutdown
|
|
|
47a30d |
+
|
|
|
47a30d |
+ :id: 5d9bd7ca-e9bf-4be9-8fc8-902aa5513052
|
|
|
47a30d |
+ :setup: Replication with two master, change nsslapd-changelogdir to
|
|
|
47a30d |
+ '/var/lib/dirsrv/slapd-master1/changelog' and
|
|
|
47a30d |
+ set cn=Retro Changelog Plugin,cn=plugins,cn=config to 'on'
|
|
|
47a30d |
+ :steps:
|
|
|
47a30d |
+ 1. Set nsslapd-changelogmaxage in cn=Retro Changelog Plugin,cn=plugins,cn=config to value '-1'
|
|
|
47a30d |
+ This value is invalid. To disable retroCL trimming it should be set to 0
|
|
|
47a30d |
+ 2. Do several restart
|
|
|
47a30d |
+ 3. check there is no 'Detected Disorderly Shutdown' message (crash)
|
|
|
47a30d |
+ 4. restore valid value for nsslapd-changelogmaxage '1w'
|
|
|
47a30d |
+
|
|
|
47a30d |
+ :expectedresults:
|
|
|
47a30d |
+ 1. Operation should be successful
|
|
|
47a30d |
+ 2. Operation should be successful
|
|
|
47a30d |
+ 3. Operation should be successful
|
|
|
47a30d |
+ 4. Operation should be successful
|
|
|
47a30d |
+ """
|
|
|
47a30d |
+ log.info('1. Test retroCL trimming crash in cn=Retro Changelog Plugin,cn=plugins,cn=config')
|
|
|
47a30d |
+
|
|
|
47a30d |
+ # set the nsslapd-changelogmaxage directly on dse.ldif
|
|
|
47a30d |
+ # because the set value is invalid
|
|
|
47a30d |
+ topo.ms["master1"].log.info("ticket50736 start verification")
|
|
|
47a30d |
+ topo.ms["master1"].stop()
|
|
|
47a30d |
+ retroPlugin = RetroChangelogPlugin(topo.ms["master1"])
|
|
|
47a30d |
+ dse_ldif = DSEldif(topo.ms["master1"])
|
|
|
47a30d |
+ dse_ldif.replace(retroPlugin.dn, 'nsslapd-changelogmaxage', '-1')
|
|
|
47a30d |
+ topo.ms["master1"].start()
|
|
|
47a30d |
+
|
|
|
47a30d |
+ # The crash should be systematic, but just in case do several restart
|
|
|
47a30d |
+ # with a delay to let all plugin init
|
|
|
47a30d |
+ for i in range(5):
|
|
|
47a30d |
+ time.sleep(1)
|
|
|
47a30d |
+ topo.ms["master1"].stop()
|
|
|
47a30d |
+ topo.ms["master1"].start()
|
|
|
47a30d |
+
|
|
|
47a30d |
+ assert not topo.ms["master1"].detectDisorderlyShutdown()
|
|
|
47a30d |
+
|
|
|
47a30d |
+ topo.ms["master1"].log.info("ticket 50736 was successfully verified.")
|
|
|
47a30d |
+
|
|
|
47a30d |
+
|
|
|
47a30d |
if __name__ == '__main__':
|
|
|
47a30d |
# Run isolated
|
|
|
47a30d |
# -s for DEBUG mode
|
|
|
47a30d |
diff --git a/ldap/servers/plugins/retrocl/retrocl_trim.c b/ldap/servers/plugins/retrocl/retrocl_trim.c
|
|
|
47a30d |
index a46534984..0378eb7f6 100644
|
|
|
47a30d |
--- a/ldap/servers/plugins/retrocl/retrocl_trim.c
|
|
|
47a30d |
+++ b/ldap/servers/plugins/retrocl/retrocl_trim.c
|
|
|
47a30d |
@@ -481,11 +481,16 @@ retrocl_init_trimming(void)
|
|
|
47a30d |
void
|
|
|
47a30d |
retrocl_stop_trimming(void)
|
|
|
47a30d |
{
|
|
|
47a30d |
- retrocl_trimming = 0;
|
|
|
47a30d |
- if (retrocl_trim_ctx) {
|
|
|
47a30d |
- slapi_eq_cancel(retrocl_trim_ctx);
|
|
|
47a30d |
- retrocl_trim_ctx = NULL;
|
|
|
47a30d |
+ if (retrocl_trimming) {
|
|
|
47a30d |
+ /* RetroCL trimming config was valid and trimming struct allocated
|
|
|
47a30d |
+ * Let's free them
|
|
|
47a30d |
+ */
|
|
|
47a30d |
+ retrocl_trimming = 0;
|
|
|
47a30d |
+ if (retrocl_trim_ctx) {
|
|
|
47a30d |
+ slapi_eq_cancel(retrocl_trim_ctx);
|
|
|
47a30d |
+ retrocl_trim_ctx = NULL;
|
|
|
47a30d |
+ }
|
|
|
47a30d |
+ PR_DestroyLock(ts.ts_s_trim_mutex);
|
|
|
47a30d |
+ ts.ts_s_trim_mutex = NULL;
|
|
|
47a30d |
}
|
|
|
47a30d |
- PR_DestroyLock(ts.ts_s_trim_mutex);
|
|
|
47a30d |
- ts.ts_s_trim_mutex = NULL;
|
|
|
47a30d |
}
|
|
|
47a30d |
--
|
|
|
47a30d |
2.21.1
|
|
|
47a30d |
|