Blame SOURCES/0009-Ticket-50736-RetroCL-trimming-may-crash-at-shutdown-.patch

8394b4
From 4ea3c4aa8118933fd22721dcf9b9e6c4a498736c Mon Sep 17 00:00:00 2001
8394b4
From: Thierry Bordaz <tbordaz@redhat.com>
8394b4
Date: Mon, 25 Nov 2019 10:59:44 +0100
8394b4
Subject: [PATCH] Ticket 50736 - RetroCL trimming may crash at shutdown if
8394b4
 trimming configuration is invalid
8394b4
8394b4
Bug Description:
8394b4
	If config of retroCL trimming contains invalid value for trim-interval
8394b4
        and/or maxage, then the trimming initialization is skipped.
8394b4
        In such case the trimming structures are not allocated and if they
8394b4
        are freed at shutdown it triggers a crash
8394b4
8394b4
Fix Description:
8394b4
        When trimming mechanism is stopped (at shutdown) check that
8394b4
        it was successfully initialized before freeing the structs
8394b4
8394b4
https://pagure.io/389-ds-base/issue/50736
8394b4
8394b4
Reviewed by: Mark Reynolds
8394b4
8394b4
Platforms tested: F30
8394b4
8394b4
Flag Day: no
8394b4
8394b4
Doc impact: no
8394b4
---
8394b4
 .../suites/replication/changelog_test.py      | 47 +++++++++++++++++++
8394b4
 ldap/servers/plugins/retrocl/retrocl_trim.c   | 17 ++++---
8394b4
 2 files changed, 58 insertions(+), 6 deletions(-)
8394b4
8394b4
diff --git a/dirsrvtests/tests/suites/replication/changelog_test.py b/dirsrvtests/tests/suites/replication/changelog_test.py
8394b4
index a257e0272..e648478d0 100644
8394b4
--- a/dirsrvtests/tests/suites/replication/changelog_test.py
8394b4
+++ b/dirsrvtests/tests/suites/replication/changelog_test.py
8394b4
@@ -16,6 +16,8 @@ from lib389.replica import Replicas
8394b4
 from lib389.idm.user import UserAccounts
8394b4
 from lib389.topologies import topology_m2 as topo
8394b4
 from lib389._constants import *
8394b4
+from lib389.plugins import RetroChangelogPlugin
8394b4
+from lib389.dseldif import DSEldif
8394b4
 from lib389.tasks import *
8394b4
 from lib389.utils import *
8394b4
 
8394b4
@@ -452,6 +454,51 @@ def test_retrochangelog_maxage(topo, changelog_init):
8394b4
 
8394b4
     topo.ms["master1"].log.info("ticket47669 was successfully verified.")
8394b4
 
8394b4
+@pytest.mark.ds50736
8394b4
+def test_retrochangelog_trimming_crash(topo, changelog_init):
8394b4
+    """Check that when retroCL nsslapd-retrocthangelog contains invalid
8394b4
+    value, then the instance does not crash at shutdown
8394b4
+
8394b4
+    :id: 5d9bd7ca-e9bf-4be9-8fc8-902aa5513052
8394b4
+    :setup: Replication with two master, change nsslapd-changelogdir to
8394b4
+    '/var/lib/dirsrv/slapd-master1/changelog' and
8394b4
+    set cn=Retro Changelog Plugin,cn=plugins,cn=config to 'on'
8394b4
+    :steps:
8394b4
+        1. Set nsslapd-changelogmaxage in cn=Retro Changelog Plugin,cn=plugins,cn=config to value '-1'
8394b4
+           This value is invalid. To disable retroCL trimming it should be set to 0
8394b4
+        2. Do several restart
8394b4
+        3. check there is no 'Detected Disorderly Shutdown' message (crash)
8394b4
+        4. restore valid value for nsslapd-changelogmaxage '1w'
8394b4
+
8394b4
+    :expectedresults:
8394b4
+        1. Operation should be successful
8394b4
+        2. Operation should be successful
8394b4
+        3. Operation should be successful
8394b4
+        4. Operation should be successful
8394b4
+     """
8394b4
+    log.info('1. Test retroCL trimming crash in cn=Retro Changelog Plugin,cn=plugins,cn=config')
8394b4
+
8394b4
+    # set the nsslapd-changelogmaxage directly on dse.ldif
8394b4
+    # because the set value is invalid
8394b4
+    topo.ms["master1"].log.info("ticket50736 start verification")
8394b4
+    topo.ms["master1"].stop()
8394b4
+    retroPlugin = RetroChangelogPlugin(topo.ms["master1"])
8394b4
+    dse_ldif = DSEldif(topo.ms["master1"])
8394b4
+    dse_ldif.replace(retroPlugin.dn, 'nsslapd-changelogmaxage', '-1')
8394b4
+    topo.ms["master1"].start()
8394b4
+
8394b4
+    # The crash should be systematic, but just in case do several restart
8394b4
+    # with a delay to let all plugin init
8394b4
+    for i in range(5):
8394b4
+        time.sleep(1)
8394b4
+        topo.ms["master1"].stop()
8394b4
+        topo.ms["master1"].start()
8394b4
+
8394b4
+    assert not topo.ms["master1"].detectDisorderlyShutdown()
8394b4
+
8394b4
+    topo.ms["master1"].log.info("ticket 50736 was successfully verified.")
8394b4
+
8394b4
+
8394b4
 
8394b4
 if __name__ == '__main__':
8394b4
     # Run isolated
8394b4
diff --git a/ldap/servers/plugins/retrocl/retrocl_trim.c b/ldap/servers/plugins/retrocl/retrocl_trim.c
8394b4
index a46534984..0378eb7f6 100644
8394b4
--- a/ldap/servers/plugins/retrocl/retrocl_trim.c
8394b4
+++ b/ldap/servers/plugins/retrocl/retrocl_trim.c
8394b4
@@ -481,11 +481,16 @@ retrocl_init_trimming(void)
8394b4
 void
8394b4
 retrocl_stop_trimming(void)
8394b4
 {
8394b4
-    retrocl_trimming = 0;
8394b4
-    if (retrocl_trim_ctx) {
8394b4
-        slapi_eq_cancel(retrocl_trim_ctx);
8394b4
-        retrocl_trim_ctx = NULL;
8394b4
+    if (retrocl_trimming) {
8394b4
+        /* RetroCL trimming config was valid and trimming struct allocated
8394b4
+         * Let's free them
8394b4
+         */
8394b4
+        retrocl_trimming = 0;
8394b4
+        if (retrocl_trim_ctx) {
8394b4
+            slapi_eq_cancel(retrocl_trim_ctx);
8394b4
+            retrocl_trim_ctx = NULL;
8394b4
+        }
8394b4
+        PR_DestroyLock(ts.ts_s_trim_mutex);
8394b4
+        ts.ts_s_trim_mutex = NULL;
8394b4
     }
8394b4
-    PR_DestroyLock(ts.ts_s_trim_mutex);
8394b4
-    ts.ts_s_trim_mutex = NULL;
8394b4
 }
8394b4
-- 
8394b4
2.21.1
8394b4