diff --git a/0065-Issue-7271-implement-a-pre-close-plugin-function.patch b/0065-Issue-7271-implement-a-pre-close-plugin-function.patch new file mode 100644 index 0000000..5664c5e --- /dev/null +++ b/0065-Issue-7271-implement-a-pre-close-plugin-function.patch @@ -0,0 +1,291 @@ +From 6fc10eae5b44989c703b67bdca157202d35d8a92 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Mon, 2 Mar 2026 14:31:29 -0500 +Subject: [PATCH] Issue 7271 - implement a pre-close plugin function + +Description: + +replication protocol could benefit from being notifioed the shutdown process +has started before calling the "close" plugin function. This would allow the +replication protocol to wake up and adjust its active thread count to prevent +a hang during shutdown. + +relates: https://github.com/389ds/389-ds-base/issues/7271 + +Reviewed by: progier, spichugi, and vashirov(Thanks!!!) +--- + ldap/servers/plugins/replication/repl5_init.c | 19 +++++++--- + ldap/servers/slapd/daemon.c | 8 +++-- + ldap/servers/slapd/pblock.c | 36 +++++++++++++------ + ldap/servers/slapd/plugin.c | 24 ++++++++++++- + ldap/servers/slapd/proto-slap.h | 3 +- + ldap/servers/slapd/slap.h | 3 +- + ldap/servers/slapd/slapi-plugin.h | 3 +- + 7 files changed, 74 insertions(+), 22 deletions(-) + +diff --git a/ldap/servers/plugins/replication/repl5_init.c b/ldap/servers/plugins/replication/repl5_init.c +index 5047fb8dc..395744db8 100644 +--- a/ldap/servers/plugins/replication/repl5_init.c ++++ b/ldap/servers/plugins/replication/repl5_init.c +@@ -1,6 +1,6 @@ + /** BEGIN COPYRIGHT BLOCK + * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. +- * Copyright (C) 2005 Red Hat, Inc. ++ * Copyright (C) 2026 Red Hat, Inc. + * All rights reserved. + * + * License: GPL (version 3 or any later version). +@@ -122,6 +122,8 @@ static PRUintn thread_private_agmtname; /* thread private index for logging*/ + static PRUintn thread_private_cache; + static PRUintn thread_primary_csn; + ++static int multisupplier_pre_stop(Slapi_PBlock *pb __attribute__((unused))); ++ + char * + get_thread_private_agmtname() + { +@@ -836,10 +838,6 @@ multisupplier_stop(Slapi_PBlock *pb __attribute__((unused))) + int rc = 0; /* OK */ + + if (!multisupplier_stopped_flag) { +- if (!is_ldif_dump) { +- /* Shut down replication agreements */ +- agmtlist_shutdown(); +- } + /* if we are cleaning a ruv, stop */ + stop_ruv_cleaning(); + /* unregister backend state change notification */ +@@ -853,6 +851,16 @@ multisupplier_stop(Slapi_PBlock *pb __attribute__((unused))) + return rc; + } + ++static int ++multisupplier_pre_stop(Slapi_PBlock *pb __attribute__((unused))) ++{ ++ if (!multisupplier_stopped_flag) { ++ /* Shut down replication agreements which will stop all the ++ * replication protocol threads */ ++ agmtlist_shutdown(); ++ } ++ return 0; ++} + + PRBool + multisupplier_started() +@@ -900,6 +908,7 @@ replication_multisupplier_plugin_init(Slapi_PBlock *pb) + rc = slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&multisupplierdesc); + rc = slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN, (void *)multisupplier_start); + rc = slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN, (void *)multisupplier_stop); ++ rc = slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_CLOSE_FN, (void *)multisupplier_pre_stop); + + /* Register the plugin interfaces we implement */ + /* preop acquires csn generator handle */ +diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c +index 19c6d7e48..7a2ca2ae2 100644 +--- a/ldap/servers/slapd/daemon.c ++++ b/ldap/servers/slapd/daemon.c +@@ -1,6 +1,6 @@ + /** BEGIN COPYRIGHT BLOCK + * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. +- * Copyright (C) 2021 Red Hat, Inc. ++ * Copyright (C) 2026 Red Hat, Inc. + * All rights reserved. + * + * License: GPL (version 3 or any later version). +@@ -1416,6 +1416,10 @@ slapd_daemon(daemon_ports_t *ports) + task_cancel_all(); + } + ++ /* Call plugin pre close functions */ ++ plugin_pre_closeall(); ++ ++ /* Now wait for active threads to terminate */ + threads = g_get_active_threadcnt(); + if (threads > 0) { + slapi_log_err(SLAPI_LOG_INFO, "slapd_daemon", +@@ -3178,7 +3182,7 @@ void + wait4certs_refresh(daemon_ports_t *ports) + { + /* +- * Block listening and accept threads until ++ * Block listening and accept threads until + * certificates refresh is complete + * Note: + * Listening threads have a NULL ports +diff --git a/ldap/servers/slapd/pblock.c b/ldap/servers/slapd/pblock.c +index 24cb9b15e..3405e6da6 100644 +--- a/ldap/servers/slapd/pblock.c ++++ b/ldap/servers/slapd/pblock.c +@@ -1,12 +1,12 @@ +-/** BEGIN COPYRIGHT BLOCK +- * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. +- * Copyright (C) 2005-2025 Red Hat, Inc. +- * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. +- * All rights reserved. +- * +- * License: GPL (version 3 or any later version). +- * See LICENSE for details. +- * END COPYRIGHT BLOCK **/ ++ /** BEGIN COPYRIGHT BLOCK ++ * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. ++ * Copyright (C) 2026 Red Hat, Inc. ++ * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. ++ * All rights reserved. ++ * ++ * License: GPL (version 3 or any later version). ++ * See LICENSE for details. ++ * END COPYRIGHT BLOCK **/ + + #ifdef HAVE_CONFIG_H + #include +@@ -1008,6 +1008,13 @@ slapi_pblock_get_plugin_close_fn(Slapi_PBlock *pblock, void *value) + return 0; + } + ++static int32_t ++slapi_pblock_get_plugin_pre_close_fn(Slapi_PBlock *pblock, void *value) ++{ ++ (*(IFP *)value) = pblock->pb_plugin->plg_pre_close; ++ return 0; ++} ++ + static int32_t + slapi_pblock_get_plugin_cleanup_fn(Slapi_PBlock *pblock, void *value) + { +@@ -4100,6 +4107,13 @@ slapi_pblock_set_plugin_close_fn(Slapi_PBlock *pblock, void *value) + return 0; + } + ++static int32_t ++slapi_pblock_set_plugin_pre_close_fn(Slapi_PBlock *pblock, void *value) ++{ ++ pblock->pb_plugin->plg_pre_close = (IFP)value; ++ return 0; ++} ++ + static int32_t + slapi_pblock_set_plugin_cleanup_fn(Slapi_PBlock *pblock, void *value) + { +@@ -6948,7 +6962,7 @@ static int32_t (*get_cbtable[])(Slapi_PBlock *, void *) = { + slapi_pblock_get_plugin_db_abandon_fn, + slapi_pblock_get_plugin_db_config_fn, + slapi_pblock_get_plugin_close_fn, +- NULL, /* slot 211 available */ ++ slapi_pblock_get_plugin_pre_close_fn, + slapi_pblock_get_plugin_start_fn, + slapi_pblock_get_plugin_db_seq_fn, + slapi_pblock_get_plugin_db_entry_fn, +@@ -8923,7 +8937,7 @@ static int32_t (*set_cbtable[])(Slapi_PBlock *, void *) = { + slapi_pblock_set_plugin_db_abandon_fn, + slapi_pblock_set_plugin_db_config_fn, + slapi_pblock_set_plugin_close_fn, +- NULL, /* slot 211 available */ ++ slapi_pblock_set_plugin_pre_close_fn, + slapi_pblock_set_plugin_start_fn, + slapi_pblock_set_plugin_db_seq_fn, + slapi_pblock_set_plugin_db_entry_fn, +diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c +index 52d25e19e..95b8de894 100644 +--- a/ldap/servers/slapd/plugin.c ++++ b/ldap/servers/slapd/plugin.c +@@ -1,6 +1,6 @@ + /** BEGIN COPYRIGHT BLOCK + * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. +- * Copyright (C) 2021 Red Hat, Inc. ++ * Copyright (C) 2026 Red Hat, Inc. + * All rights reserved. + * + * License: GPL (version 3 or any later version). +@@ -1847,6 +1847,28 @@ plugin_dependency_closeall(void) + } + } + ++/* Call the pre close functions of all the plugins */ ++void ++plugin_pre_closeall(void) ++{ ++ Slapi_PBlock *pb = NULL; ++ int plugins_pre_closed = 0; ++ int index = 0; ++ ++ while (plugins_pre_closed < global_plugins_started) { ++ if (global_plugin_shutdown_order[index].name) { ++ if (!global_plugin_shutdown_order[index].removed) { ++ pb = slapi_pblock_new(); ++ plugin_call_one(global_plugin_shutdown_order[index].plugin, ++ SLAPI_PLUGIN_PRE_CLOSE_FN, pb); ++ slapi_pblock_destroy(pb); ++ } ++ plugins_pre_closed++; ++ } ++ index++; ++ } ++} ++ + void + plugin_freeall(void) + { +diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h +index 455d6d718..ce7e4f047 100644 +--- a/ldap/servers/slapd/proto-slap.h ++++ b/ldap/servers/slapd/proto-slap.h +@@ -1,6 +1,6 @@ + /** BEGIN COPYRIGHT BLOCK + * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. +- * Copyright (C) 2021-2025 Red Hat, Inc. ++ * Copyright (C) 2026 Red Hat, Inc. + * All rights reserved. + * + * License: GPL (version 3 or any later version). +@@ -997,6 +997,7 @@ int plugin_call_exop_plugins(Slapi_PBlock *pb, struct slapdplugin *p); + Slapi_Backend *plugin_extended_op_getbackend(Slapi_PBlock *pb, struct slapdplugin *p); + const char *plugin_extended_op_oid2string(const char *oid); + void plugin_closeall(int close_backends, int close_globals); ++void plugin_pre_closeall(void); + void plugin_dependency_freeall(void); + void plugin_startall(int argc, char **argv, char **plugin_list); + void plugin_get_plugin_dependencies(char *plugin_name, char ***names); +diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h +index d494931c2..3e50f77b2 100644 +--- a/ldap/servers/slapd/slap.h ++++ b/ldap/servers/slapd/slap.h +@@ -1,7 +1,7 @@ + /** BEGIN COPYRIGHT BLOCK + * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. + * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. +- * Copyright (C) 2009-2025 Red Hat, Inc. ++ * Copyright (C) 2026 Red Hat, Inc. + * All rights reserved. + * + * Contributors: +@@ -1046,6 +1046,7 @@ struct slapdplugin + char *plg_libpath; /* library path for dll/so */ + char *plg_initfunc; /* init symbol */ + IFP plg_close; /* close function */ ++ IFP plg_pre_close; /* pre close function */ + Slapi_PluginDesc plg_desc; /* vendor's info */ + char *plg_name; /* used for plugin rdn in cn=config */ + struct slapdplugin *plg_next; /* for plugin lists */ +diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h +index 85bbf8fa1..70677123d 100644 +--- a/ldap/servers/slapd/slapi-plugin.h ++++ b/ldap/servers/slapd/slapi-plugin.h +@@ -1,6 +1,6 @@ + /* BEGIN COPYRIGHT BLOCK + * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. +- * Copyright (C) 2021 Red Hat, Inc. ++ * Copyright (C) 2026 Red Hat, Inc. + * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. + * All rights reserved. + * +@@ -7085,6 +7085,7 @@ typedef struct slapi_plugindesc + + /* miscellaneous plugin functions */ + #define SLAPI_PLUGIN_CLOSE_FN 210 ++#define SLAPI_PLUGIN_PRE_CLOSE_FN 211 + #define SLAPI_PLUGIN_START_FN 212 + #define SLAPI_PLUGIN_CLEANUP_FN 232 + #define SLAPI_PLUGIN_POSTSTART_FN 233 +-- +2.53.0 + diff --git a/0066-Issue-7271-Add-new-plugin-pre-close-function-check-t.patch b/0066-Issue-7271-Add-new-plugin-pre-close-function-check-t.patch new file mode 100644 index 0000000..40b95ed --- /dev/null +++ b/0066-Issue-7271-Add-new-plugin-pre-close-function-check-t.patch @@ -0,0 +1,34 @@ +From 5cc3edb9732784e8a3edb033962b6312f2bb7b55 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Wed, 4 Mar 2026 14:47:01 -0500 +Subject: [PATCH] Issue 7271 - Add new plugin pre-close function check to + plugin_invoke_plugin_pb + +Description: + +In plugin_invoke_plugin_pb we were not checking for the new pre-close function +which led to an error in the logs: pb_op is NULL. In a debug build this leads +to an assertion error at shutdown. + +relates: https://github.com/389ds/389-ds-base/issues/7271 + +Reviewed by: vashirov(Thanks!) +--- + ldap/servers/slapd/plugin.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c +index 95b8de894..c1b0571eb 100644 +--- a/ldap/servers/slapd/plugin.c ++++ b/ldap/servers/slapd/plugin.c +@@ -3647,6 +3647,7 @@ plugin_invoke_plugin_pb(struct slapdplugin *plugin, int operation, Slapi_PBlock + if (operation == SLAPI_PLUGIN_START_FN || + operation == SLAPI_PLUGIN_POSTSTART_FN || + operation == SLAPI_PLUGIN_CLOSE_FN || ++ operation == SLAPI_PLUGIN_PRE_CLOSE_FN || + operation == SLAPI_PLUGIN_CLEANUP_FN || + operation == SLAPI_PLUGIN_BE_PRE_CLOSE_FN || + operation == SLAPI_PLUGIN_BE_POST_OPEN_FN || +-- +2.53.0 + diff --git a/389-ds-base.spec b/389-ds-base.spec index aad3a1e..19ea8c8 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -345,6 +345,8 @@ Patch: 0061-Issue-7275-UI-Improve-password-policy-field-validati.patc Patch: 0062-Issue-7246-correct-formatting-of-Gen-as-CSN-in-dsctl.patch Patch: 0063-Security-fix-for-CVE-2025-14905.patch Patch: 0064-Issue-7267-MDB_BAD_VALSIZE-error-when-updating-index.patch +Patch: 0065-Issue-7271-implement-a-pre-close-plugin-function.patch +Patch: 0066-Issue-7271-Add-new-plugin-pre-close-function-check-t.patch %description 389 Directory Server is an LDAPv3 compliant server. The base package includes