- Fix Issue-5789-Improve-ds-replcheck-error-handling.patch
- Fix Issue-5646-Various-memory-leaks-5725.patch - Fix Issue-2375-CLI-Healthcheck-revise-and-add-new-checks.patch - Fix Issue-4551-Paged-search-impacts-performance-5838.patch - Fix Issue-5804-dtablesize-being-set-to-soft-maxfiledescr.patch - Fix Issue-5825-healthcheck-password-storage-scheme-warni.patch - Fix Issue-5864-Server-fails-to-start-after-reboot-becaus.patch - Fix Issue-5883-Remove-connection-mutex-contention-risk-o.patch
This commit is contained in:
parent
91e5547fc3
commit
2cea32f1ac
@ -0,0 +1,440 @@
|
|||||||
|
From ea3d4e8b519297baab158eba6fa2b75ab3c30dbb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mark Reynolds <mreynolds@redhat.com>
|
||||||
|
Date: Thu, 22 Jun 2023 16:33:55 -0400
|
||||||
|
Subject: [PATCH] Issue 2375 - CLI - Healthcheck - revise and add new checks
|
||||||
|
|
||||||
|
Description:
|
||||||
|
|
||||||
|
Add check for
|
||||||
|
|
||||||
|
- unauthorized binds are allowed
|
||||||
|
- Access log buffering is disabled
|
||||||
|
- Make mapping tree check more robust for case
|
||||||
|
|
||||||
|
relates: https://github.com/389ds/389-ds-base/issues/2375
|
||||||
|
|
||||||
|
Reviewed by: spichugi(Thanks!)
|
||||||
|
---
|
||||||
|
.../suites/healthcheck/health_config_test.py | 80 ++++++++++++++++++-
|
||||||
|
.../suites/healthcheck/healthcheck_test.py | 15 +++-
|
||||||
|
src/cockpit/389-console/package-lock.json | 36 ++++-----
|
||||||
|
src/lib389/lib389/backend.py | 4 +-
|
||||||
|
src/lib389/lib389/config.py | 24 +++++-
|
||||||
|
src/lib389/lib389/lint.py | 32 +++++++-
|
||||||
|
6 files changed, 163 insertions(+), 28 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dirsrvtests/tests/suites/healthcheck/health_config_test.py b/dirsrvtests/tests/suites/healthcheck/health_config_test.py
|
||||||
|
index f0337f198f..6d3d08bfae 100644
|
||||||
|
--- a/dirsrvtests/tests/suites/healthcheck/health_config_test.py
|
||||||
|
+++ b/dirsrvtests/tests/suites/healthcheck/health_config_test.py
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
# --- BEGIN COPYRIGHT BLOCK ---
|
||||||
|
-# Copyright (C) 2022 Red Hat, Inc.
|
||||||
|
+# Copyright (C) 2023 Red Hat, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# License: GPL (version 3 or any later version).
|
||||||
|
@@ -11,7 +11,7 @@
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
-from lib389.backend import Backends
|
||||||
|
+from lib389.backend import Backends, DatabaseConfig
|
||||||
|
from lib389.cos import CosTemplates, CosPointerDefinitions
|
||||||
|
from lib389.dbgen import dbgen_users
|
||||||
|
from lib389.idm.account import Accounts
|
||||||
|
@@ -119,6 +119,7 @@ def test_healthcheck_logging_format_should_be_revised(topology_st):
|
||||||
|
|
||||||
|
log.info('Set nsslapd-logging-hr-timestamps-enabled to off')
|
||||||
|
standalone.config.set('nsslapd-logging-hr-timestamps-enabled', 'off')
|
||||||
|
+ standalone.config.set("nsslapd-accesslog-logbuffering", "on")
|
||||||
|
|
||||||
|
run_healthcheck_and_flush_log(topology_st, standalone, json=False, searched_code=RET_CODE)
|
||||||
|
run_healthcheck_and_flush_log(topology_st, standalone, json=True, searched_code=RET_CODE)
|
||||||
|
@@ -364,6 +365,7 @@ def test_healthcheck_low_disk_space(topology_st):
|
||||||
|
RET_CODE = 'DSDSLE0001'
|
||||||
|
|
||||||
|
standalone = topology_st.standalone
|
||||||
|
+ standalone.config.set("nsslapd-accesslog-logbuffering", "on")
|
||||||
|
file = '{}/foo'.format(standalone.ds_paths.log_dir)
|
||||||
|
|
||||||
|
log.info('Count the disk space to allocate')
|
||||||
|
@@ -411,10 +413,13 @@ def test_healthcheck_notes_unindexed_search(topology_st, setup_ldif):
|
||||||
|
standalone = topology_st.standalone
|
||||||
|
|
||||||
|
log.info('Delete the previous access logs')
|
||||||
|
- topology_st.standalone.deleteAccessLogs()
|
||||||
|
+ standalone.deleteAccessLogs()
|
||||||
|
|
||||||
|
log.info('Set nsslapd-accesslog-logbuffering to off')
|
||||||
|
standalone.config.set("nsslapd-accesslog-logbuffering", "off")
|
||||||
|
+ db_cfg = DatabaseConfig(standalone)
|
||||||
|
+ db_cfg.set([('nsslapd-idlistscanlimit', '100')])
|
||||||
|
+
|
||||||
|
|
||||||
|
log.info('Stopping the server and running offline import...')
|
||||||
|
standalone.stop()
|
||||||
|
@@ -429,6 +434,8 @@ def test_healthcheck_notes_unindexed_search(topology_st, setup_ldif):
|
||||||
|
log.info('Check that access log contains "notes=A"')
|
||||||
|
assert standalone.ds_access_log.match(r'.*notes=A.*')
|
||||||
|
|
||||||
|
+ standalone.config.set("nsslapd-accesslog-logbuffering", "on")
|
||||||
|
+
|
||||||
|
run_healthcheck_and_flush_log(topology_st, standalone, RET_CODE, json=False)
|
||||||
|
run_healthcheck_and_flush_log(topology_st, standalone, RET_CODE, json=True)
|
||||||
|
|
||||||
|
@@ -464,6 +471,8 @@ def test_healthcheck_notes_unknown_attribute(topology_st, setup_ldif):
|
||||||
|
|
||||||
|
log.info('Set nsslapd-accesslog-logbuffering to off')
|
||||||
|
standalone.config.set("nsslapd-accesslog-logbuffering", "off")
|
||||||
|
+ db_cfg = DatabaseConfig(standalone)
|
||||||
|
+ db_cfg.set([('nsslapd-idlistscanlimit', '100')])
|
||||||
|
|
||||||
|
log.info('Stopping the server and running offline import...')
|
||||||
|
standalone.stop()
|
||||||
|
@@ -478,9 +487,74 @@ def test_healthcheck_notes_unknown_attribute(topology_st, setup_ldif):
|
||||||
|
log.info('Check that access log contains "notes=F"')
|
||||||
|
assert standalone.ds_access_log.match(r'.*notes=F.*')
|
||||||
|
|
||||||
|
+ standalone.config.set("nsslapd-accesslog-logbuffering", "on")
|
||||||
|
run_healthcheck_and_flush_log(topology_st, standalone, RET_CODE, json=False)
|
||||||
|
run_healthcheck_and_flush_log(topology_st, standalone, RET_CODE, json=True)
|
||||||
|
|
||||||
|
+def test_healthcheck_unauth_binds(topology_st):
|
||||||
|
+ """Check if HealthCheck returns DSCLE0003 code when unauthorized binds are
|
||||||
|
+ allowed
|
||||||
|
+
|
||||||
|
+ :id: 13b88a3b-0dc5-4ce9-9fbf-058ad072339b
|
||||||
|
+ :setup: Standalone instance
|
||||||
|
+ :steps:
|
||||||
|
+ 1. Create DS instance
|
||||||
|
+ 2. Set nsslapd-allow-unauthenticated-binds to on
|
||||||
|
+ 3. Use HealthCheck without --json option
|
||||||
|
+ 4. Use HealthCheck with --json option
|
||||||
|
+ :expectedresults:
|
||||||
|
+ 1. Success
|
||||||
|
+ 2. Success
|
||||||
|
+ 3. Healthcheck reports DSCLE0003
|
||||||
|
+ 4. Healthcheck reports DSCLE0003
|
||||||
|
+ """
|
||||||
|
+
|
||||||
|
+ RET_CODE = 'DSCLE0003'
|
||||||
|
+
|
||||||
|
+ inst = topology_st.standalone
|
||||||
|
+
|
||||||
|
+ log.info('nsslapd-allow-unauthenticated-binds to on')
|
||||||
|
+ inst.config.set("nsslapd-allow-unauthenticated-binds", "on")
|
||||||
|
+
|
||||||
|
+ run_healthcheck_and_flush_log(topology_st, inst, RET_CODE, json=False)
|
||||||
|
+ run_healthcheck_and_flush_log(topology_st, inst, RET_CODE, json=True)
|
||||||
|
+
|
||||||
|
+ # reset setting
|
||||||
|
+ log.info('Reset nsslapd-allow-unauthenticated-binds to off')
|
||||||
|
+ inst.config.set("nsslapd-allow-unauthenticated-binds", "off")
|
||||||
|
+
|
||||||
|
+def test_healthcheck_accesslog_buffering(topology_st):
|
||||||
|
+ """Check if HealthCheck returns DSCLE0004 code when acccess log biffering
|
||||||
|
+ is disabled
|
||||||
|
+
|
||||||
|
+ :id: 5a6512fd-1c7b-4557-9278-45150423148b
|
||||||
|
+ :setup: Standalone instance
|
||||||
|
+ :steps:
|
||||||
|
+ 1. Create DS instance
|
||||||
|
+ 2. Set nsslapd-accesslog-logbuffering to off
|
||||||
|
+ 3. Use HealthCheck without --json option
|
||||||
|
+ 4. Use HealthCheck with --json option
|
||||||
|
+ :expectedresults:
|
||||||
|
+ 1. Success
|
||||||
|
+ 2. Success
|
||||||
|
+ 3. Healthcheck reports DSCLE0004
|
||||||
|
+ 4. Healthcheck reports DSCLE0004
|
||||||
|
+ """
|
||||||
|
+
|
||||||
|
+ RET_CODE = 'DSCLE0004'
|
||||||
|
+
|
||||||
|
+ inst = topology_st.standalone
|
||||||
|
+
|
||||||
|
+ log.info('nsslapd-accesslog-logbuffering to off')
|
||||||
|
+ inst.config.set("nsslapd-accesslog-logbuffering", "off")
|
||||||
|
+
|
||||||
|
+ run_healthcheck_and_flush_log(topology_st, inst, RET_CODE, json=False)
|
||||||
|
+ run_healthcheck_and_flush_log(topology_st, inst, RET_CODE, json=True)
|
||||||
|
+
|
||||||
|
+ # reset setting
|
||||||
|
+ log.info('Reset nsslapd-accesslog-logbuffering to on')
|
||||||
|
+ inst.config.set("nsslapd-accesslog-logbuffering", "on")
|
||||||
|
+
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
# Run isolated
|
||||||
|
diff --git a/dirsrvtests/tests/suites/healthcheck/healthcheck_test.py b/dirsrvtests/tests/suites/healthcheck/healthcheck_test.py
|
||||||
|
index 1c83b53ff3..83b5290244 100644
|
||||||
|
--- a/dirsrvtests/tests/suites/healthcheck/healthcheck_test.py
|
||||||
|
+++ b/dirsrvtests/tests/suites/healthcheck/healthcheck_test.py
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
# --- BEGIN COPYRIGHT BLOCK ---
|
||||||
|
-# Copyright (C) 2020 Red Hat, Inc.
|
||||||
|
+# Copyright (C) 2023 Red Hat, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# License: GPL (version 3 or any later version).
|
||||||
|
@@ -91,6 +91,7 @@ def test_healthcheck_disabled_suffix(topology_st):
|
||||||
|
mts = MappingTrees(topology_st.standalone)
|
||||||
|
mt = mts.get(DEFAULT_SUFFIX)
|
||||||
|
mt.replace("nsslapd-state", "disabled")
|
||||||
|
+ topology_st.standalone.config.set("nsslapd-accesslog-logbuffering", "on")
|
||||||
|
|
||||||
|
run_healthcheck_and_flush_log(topology_st, topology_st.standalone, RET_CODE, json=False)
|
||||||
|
run_healthcheck_and_flush_log(topology_st, topology_st.standalone, RET_CODE, json=True)
|
||||||
|
@@ -187,6 +188,8 @@ def test_healthcheck_list_errors(topology_st):
|
||||||
|
'DSCERTLE0002 :: Certificate expired',
|
||||||
|
'DSCLE0001 :: Different log timestamp format',
|
||||||
|
'DSCLE0002 :: Weak passwordStorageScheme',
|
||||||
|
+ 'DSCLE0003 :: Unauthorized Binds Allowed',
|
||||||
|
+ 'DSCLE0004 :: Access Log buffering disabled',
|
||||||
|
'DSCLLE0001 :: Changelog trimming not configured',
|
||||||
|
'DSDSLE0001 :: Low disk space',
|
||||||
|
'DSELE0001 :: Weak TLS protocol version',
|
||||||
|
@@ -231,6 +234,8 @@ def test_healthcheck_check_option(topology_st):
|
||||||
|
|
||||||
|
output_list = ['config:hr_timestamp',
|
||||||
|
'config:passwordscheme',
|
||||||
|
+ # 'config:accesslog_buffering', Skip test access log buffering is disabled
|
||||||
|
+ 'config:unauth_binds',
|
||||||
|
'backends:userroot:mappingtree',
|
||||||
|
'backends:userroot:search',
|
||||||
|
'backends:userroot:virt_attrs',
|
||||||
|
@@ -238,9 +243,11 @@ def test_healthcheck_check_option(topology_st):
|
||||||
|
'fschecks:file_perms',
|
||||||
|
'refint:attr_indexes',
|
||||||
|
'refint:update_delay',
|
||||||
|
+ 'memberof:member_attr_indexes',
|
||||||
|
'monitor-disk-space:disk_space',
|
||||||
|
'replication:agmts_status',
|
||||||
|
'replication:conflicts',
|
||||||
|
+ 'replication:no_ruv',
|
||||||
|
'dseldif:nsstate',
|
||||||
|
'tls:certificate_expiration',
|
||||||
|
'logs:notes']
|
||||||
|
@@ -308,6 +315,8 @@ def test_healthcheck_replication(topology_m2):
|
||||||
|
# If we don't set changelog trimming, we will get error DSCLLE0001
|
||||||
|
set_changelog_trimming(M1)
|
||||||
|
set_changelog_trimming(M2)
|
||||||
|
+ M1.config.set("nsslapd-accesslog-logbuffering", "on")
|
||||||
|
+ M2.config.set("nsslapd-accesslog-logbuffering", "on")
|
||||||
|
|
||||||
|
log.info('Run healthcheck for supplier1')
|
||||||
|
run_healthcheck_and_flush_log(topology_m2, M1, CMD_OUTPUT, json=False)
|
||||||
|
@@ -347,6 +356,8 @@ def test_healthcheck_replication_tls(topology_m2):
|
||||||
|
M2.enable_tls()
|
||||||
|
|
||||||
|
log.info('Run healthcheck for supplier1')
|
||||||
|
+ M1.config.set("nsslapd-accesslog-logbuffering", "on")
|
||||||
|
+ M2.config.set("nsslapd-accesslog-logbuffering", "on")
|
||||||
|
run_healthcheck_and_flush_log(topology_m2, M1, CMD_OUTPUT, json=False)
|
||||||
|
run_healthcheck_and_flush_log(topology_m2, M1, JSON_OUTPUT, json=True)
|
||||||
|
|
||||||
|
@@ -399,7 +410,7 @@ def test_healthcheck_backend_missing_mapping_tree(topology_st):
|
||||||
|
mts.create(properties={
|
||||||
|
'cn': DEFAULT_SUFFIX,
|
||||||
|
'nsslapd-state': 'backend',
|
||||||
|
- 'nsslapd-backend': 'userRoot',
|
||||||
|
+ 'nsslapd-backend': 'USERROOT',
|
||||||
|
})
|
||||||
|
|
||||||
|
run_healthcheck_and_flush_log(topology_st, standalone, CMD_OUTPUT, json=False)
|
||||||
|
diff --git a/src/cockpit/389-console/package-lock.json b/src/cockpit/389-console/package-lock.json
|
||||||
|
index 787cc6b7af..cf2b4665cc 100644
|
||||||
|
--- a/src/cockpit/389-console/package-lock.json
|
||||||
|
+++ b/src/cockpit/389-console/package-lock.json
|
||||||
|
@@ -2657,9 +2657,9 @@
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/audit-ci/node_modules/semver": {
|
||||||
|
- "version": "7.3.8",
|
||||||
|
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
|
||||||
|
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
|
||||||
|
+ "version": "7.5.3",
|
||||||
|
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz",
|
||||||
|
+ "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"lru-cache": "^6.0.0"
|
||||||
|
@@ -3240,9 +3240,9 @@
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/css-loader/node_modules/semver": {
|
||||||
|
- "version": "7.3.8",
|
||||||
|
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
|
||||||
|
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
|
||||||
|
+ "version": "7.5.3",
|
||||||
|
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz",
|
||||||
|
+ "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"lru-cache": "^6.0.0"
|
||||||
|
@@ -4469,9 +4469,9 @@
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint/node_modules/semver": {
|
||||||
|
- "version": "7.3.8",
|
||||||
|
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
|
||||||
|
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
|
||||||
|
+ "version": "7.5.3",
|
||||||
|
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz",
|
||||||
|
+ "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"lru-cache": "^6.0.0"
|
||||||
|
},
|
||||||
|
@@ -10677,9 +10677,9 @@
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"semver": {
|
||||||
|
- "version": "7.3.8",
|
||||||
|
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
|
||||||
|
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
|
||||||
|
+ "version": "7.5.3",
|
||||||
|
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz",
|
||||||
|
+ "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"lru-cache": "^6.0.0"
|
||||||
|
@@ -11097,9 +11097,9 @@
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"semver": {
|
||||||
|
- "version": "7.3.8",
|
||||||
|
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
|
||||||
|
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
|
||||||
|
+ "version": "7.5.3",
|
||||||
|
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz",
|
||||||
|
+ "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"lru-cache": "^6.0.0"
|
||||||
|
@@ -11699,9 +11699,9 @@
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"semver": {
|
||||||
|
- "version": "7.3.8",
|
||||||
|
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
|
||||||
|
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
|
||||||
|
+ "version": "7.5.3",
|
||||||
|
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz",
|
||||||
|
+ "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==",
|
||||||
|
"requires": {
|
||||||
|
"lru-cache": "^6.0.0"
|
||||||
|
}
|
||||||
|
diff --git a/src/lib389/lib389/backend.py b/src/lib389/lib389/backend.py
|
||||||
|
index d1094aa613..9acced2054 100644
|
||||||
|
--- a/src/lib389/lib389/backend.py
|
||||||
|
+++ b/src/lib389/lib389/backend.py
|
||||||
|
@@ -498,11 +498,11 @@ def _lint_mappingtree(self):
|
||||||
|
* missing indices if we are local and have log access?
|
||||||
|
"""
|
||||||
|
# Check for the missing mapping tree.
|
||||||
|
- suffix = self.get_attr_val_utf8('nsslapd-suffix')
|
||||||
|
+ suffix = self.get_attr_val_utf8_l('nsslapd-suffix')
|
||||||
|
bename = self.lint_uid()
|
||||||
|
try:
|
||||||
|
mt = self._mts.get(suffix)
|
||||||
|
- if mt.get_attr_val_utf8('nsslapd-backend') != bename and mt.get_attr_val_utf8('nsslapd-state') != 'backend':
|
||||||
|
+ if mt.get_attr_val_utf8_l('nsslapd-backend') != bename.lower() and mt.get_attr_val_utf8('nsslapd-state') != 'backend':
|
||||||
|
raise ldap.NO_SUCH_OBJECT("We have a matching suffix, but not a backend or correct database name.")
|
||||||
|
except ldap.NO_SUCH_OBJECT:
|
||||||
|
result = DSBLE0001
|
||||||
|
diff --git a/src/lib389/lib389/config.py b/src/lib389/lib389/config.py
|
||||||
|
index 00d38463a0..b1a474ebed 100644
|
||||||
|
--- a/src/lib389/lib389/config.py
|
||||||
|
+++ b/src/lib389/lib389/config.py
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
# --- BEGIN COPYRIGHT BLOCK ---
|
||||||
|
-# Copyright (C) 2020 Red Hat, Inc.
|
||||||
|
+# Copyright (C) 2023 Red Hat, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# License: GPL (version 3 or any later version).
|
||||||
|
@@ -22,7 +22,9 @@
|
||||||
|
from lib389 import Entry
|
||||||
|
from lib389._mapped_object import DSLdapObject
|
||||||
|
from lib389.utils import ensure_bytes, selinux_label_port, selinux_present
|
||||||
|
-from lib389.lint import DSCLE0001, DSCLE0002, DSELE0001
|
||||||
|
+from lib389.lint import (
|
||||||
|
+ DSCLE0001, DSCLE0002, DSCLE0003, DSCLE0004, DSELE0001
|
||||||
|
+)
|
||||||
|
|
||||||
|
class Config(DSLdapObject):
|
||||||
|
"""
|
||||||
|
@@ -218,6 +220,24 @@ def _lint_passwordscheme(self):
|
||||||
|
report['check'] = "config:passwordscheme"
|
||||||
|
yield report
|
||||||
|
|
||||||
|
+ def _lint_unauth_binds(self):
|
||||||
|
+ # Allow unauthenticated binds
|
||||||
|
+ unauthbinds = self.get_attr_val_utf8_l('nsslapd-allow-unauthenticated-binds')
|
||||||
|
+ if unauthbinds == "on":
|
||||||
|
+ report = copy.deepcopy(DSCLE0003)
|
||||||
|
+ report['fix'] = report['fix'].replace('YOUR_INSTANCE', self._instance.serverid)
|
||||||
|
+ report['check'] = "config:unauthorizedbinds"
|
||||||
|
+ yield report
|
||||||
|
+
|
||||||
|
+ def _lint_accesslog_buffering(self):
|
||||||
|
+ # access log buffering
|
||||||
|
+ buffering = self.get_attr_val_utf8_l('nsslapd-accesslog-logbuffering')
|
||||||
|
+ if buffering == "off":
|
||||||
|
+ report = copy.deepcopy(DSCLE0004)
|
||||||
|
+ report['fix'] = report['fix'].replace('YOUR_INSTANCE', self._instance.serverid)
|
||||||
|
+ report['check'] = "config:accesslogbuffering"
|
||||||
|
+ yield report
|
||||||
|
+
|
||||||
|
def disable_plaintext_port(self):
|
||||||
|
"""
|
||||||
|
Configure the server to not-provide the plaintext port.
|
||||||
|
diff --git a/src/lib389/lib389/lint.py b/src/lib389/lib389/lint.py
|
||||||
|
index 0219801f48..7ca524315d 100644
|
||||||
|
--- a/src/lib389/lib389/lint.py
|
||||||
|
+++ b/src/lib389/lib389/lint.py
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
# --- BEGIN COPYRIGHT BLOCK ---
|
||||||
|
-# Copyright (C) 2022 Red Hat, Inc.
|
||||||
|
+# Copyright (C) 2023 Red Hat, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# License: GPL (version 3 or any later version).
|
||||||
|
@@ -113,6 +113,36 @@
|
||||||
|
# dsconf slapd-YOUR_INSTANCE config replace passwordStorageScheme=PBKDF2-SHA512 nsslapd-rootpwstoragescheme=PBKDF2-SHA512"""
|
||||||
|
}
|
||||||
|
|
||||||
|
+DSCLE0003 = {
|
||||||
|
+ 'dsle': 'DSCLE0003',
|
||||||
|
+ 'severity': 'MEDIUM',
|
||||||
|
+ 'description': 'Unauthorized Binds Allowed',
|
||||||
|
+ 'items': ['cn=config', ],
|
||||||
|
+ 'detail': """nsslapd-allow-unauthenticated-binds is set to 'on' this can
|
||||||
|
+lead to unexpected results with clients and potential security issues
|
||||||
|
+""",
|
||||||
|
+ 'fix': """Set nsslapd-allow-unauthenticated-binds to off.
|
||||||
|
+You can use 'dsconf' to set this attribute. Here is an example:
|
||||||
|
+
|
||||||
|
+ # dsconf slapd-YOUR_INSTANCE config replace nsslapd-allow-unauthenticated-binds=off"""
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+DSCLE0004 = {
|
||||||
|
+ 'dsle': 'DSCLE0004',
|
||||||
|
+ 'severity': 'LOW',
|
||||||
|
+ 'description': 'Access Log buffering disabled',
|
||||||
|
+ 'items': ['cn=config', ],
|
||||||
|
+ 'detail': """nsslapd-accesslog-logbuffering is set to 'off' this will cause high
|
||||||
|
+disk IO and can significantly impact server performance. This should only be used
|
||||||
|
+for debug purposes
|
||||||
|
+""",
|
||||||
|
+ 'fix': """Set nsslapd-accesslog-logbuffering to 'on'.
|
||||||
|
+You can use 'dsconf' to set this attribute. Here is an example:
|
||||||
|
+
|
||||||
|
+ # dsconf slapd-YOUR_INSTANCE config replace nsslapd-accesslog-logbuffering=on
|
||||||
|
+"""
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
# Security checks
|
||||||
|
DSELE0001 = {
|
||||||
|
'dsle': 'DSELE0001',
|
612
SOURCES/Issue-4551-Paged-search-impacts-performance-5838.patch
Normal file
612
SOURCES/Issue-4551-Paged-search-impacts-performance-5838.patch
Normal file
@ -0,0 +1,612 @@
|
|||||||
|
From a6f0981de89657134981daf8d914a86eae3793f8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: progier389 <progier@redhat.com>
|
||||||
|
Date: Tue, 18 Jul 2023 11:17:07 +0200
|
||||||
|
Subject: [PATCH] Issue 4551 - Paged search impacts performance (#5838)
|
||||||
|
|
||||||
|
Problem:
|
||||||
|
Having a script looping doing a search with paged result impact greatly the performance of other clients
|
||||||
|
(for example ldclt bind+search rate decreased by 80% in the test case)
|
||||||
|
|
||||||
|
Cause:
|
||||||
|
Page result field in connection were protected by the connection mutex that is also used by the listener thread, in some cases this cause contention that delays the handling of new operations
|
||||||
|
|
||||||
|
Solution:
|
||||||
|
Do not rely on the connection mutex to protect the page result context but on a dedicated array of locks.
|
||||||
|
|
||||||
|
(cherry picked from commit 3c510e0a26e321949b552b5e8c887634d9d7e63e)
|
||||||
|
---
|
||||||
|
ldap/servers/slapd/daemon.c | 1 +
|
||||||
|
ldap/servers/slapd/main.c | 2 +
|
||||||
|
ldap/servers/slapd/opshared.c | 26 +++---
|
||||||
|
ldap/servers/slapd/pagedresults.c | 134 ++++++++++++++++++------------
|
||||||
|
ldap/servers/slapd/proto-slap.h | 3 +
|
||||||
|
5 files changed, 101 insertions(+), 65 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
|
||||||
|
index 9eed678927..388fa09431 100644
|
||||||
|
--- a/ldap/servers/slapd/daemon.c
|
||||||
|
+++ b/ldap/servers/slapd/daemon.c
|
||||||
|
@@ -1367,6 +1367,7 @@ slapd_daemon(daemon_ports_t *ports)
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE, "slapd_daemon",
|
||||||
|
"slapd shutting down - waiting for backends to close down\n");
|
||||||
|
|
||||||
|
+ pageresult_lock_cleanup();
|
||||||
|
eq_stop(); /* deprecated */
|
||||||
|
eq_stop_rel();
|
||||||
|
if (!in_referral_mode) {
|
||||||
|
diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
|
||||||
|
index fe7f74e910..ed2de90b1d 100644
|
||||||
|
--- a/ldap/servers/slapd/main.c
|
||||||
|
+++ b/ldap/servers/slapd/main.c
|
||||||
|
@@ -989,6 +989,7 @@ main(int argc, char **argv)
|
||||||
|
eq_init_rel(); /* must be done before plugins started */
|
||||||
|
|
||||||
|
ps_init_psearch_system(); /* must come before plugin_startall() */
|
||||||
|
+ pageresult_lock_init();
|
||||||
|
|
||||||
|
|
||||||
|
/* initialize UniqueID generator - must be done once backends are started
|
||||||
|
@@ -2214,6 +2215,7 @@ slapd_exemode_db2ldif(int argc, char **argv, struct main_config *mcfg)
|
||||||
|
eq_init_rel(); /* must be done before plugins started */
|
||||||
|
|
||||||
|
ps_init_psearch_system(); /* must come before plugin_startall() */
|
||||||
|
+ pageresult_lock_init();
|
||||||
|
plugin_startall(argc, argv, plugin_list);
|
||||||
|
eq_start(); /* must be done after plugins started - DEPRECATED*/
|
||||||
|
eq_start_rel(); /* must be done after plugins started */
|
||||||
|
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
|
||||||
|
index 905a81f0f7..897b9566e5 100644
|
||||||
|
--- a/ldap/servers/slapd/opshared.c
|
||||||
|
+++ b/ldap/servers/slapd/opshared.c
|
||||||
|
@@ -271,6 +271,7 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
|
||||||
|
int pr_idx = -1;
|
||||||
|
Slapi_DN *orig_sdn = NULL;
|
||||||
|
int free_sdn = 0;
|
||||||
|
+ pthread_mutex_t *pagedresults_mutex = NULL;
|
||||||
|
|
||||||
|
be_list[0] = NULL;
|
||||||
|
referral_list[0] = NULL;
|
||||||
|
@@ -577,6 +578,7 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
|
||||||
|
int32_t tlimit;
|
||||||
|
slapi_pblock_get(pb, SLAPI_SEARCH_TIMELIMIT, &tlimit);
|
||||||
|
pagedresults_set_timelimit(pb_conn, operation, (time_t)tlimit, pr_idx);
|
||||||
|
+ pagedresults_mutex = pageresult_lock_get_addr(pb_conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -694,10 +696,10 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
|
||||||
|
/* PAGED RESULTS and already have the search results from the prev op */
|
||||||
|
pagedresults_lock(pb_conn, pr_idx);
|
||||||
|
/*
|
||||||
|
- * In async paged result case, the search result might be released
|
||||||
|
- * by other theads. We need to double check it in the locked region.
|
||||||
|
- */
|
||||||
|
- pthread_mutex_lock(&(pb_conn->c_mutex));
|
||||||
|
+ * In async paged result case, the search result might be released
|
||||||
|
+ * by other theads. We need to double check it in the locked region.
|
||||||
|
+ */
|
||||||
|
+ pthread_mutex_lock(pagedresults_mutex);
|
||||||
|
pr_search_result = pagedresults_get_search_result(pb_conn, operation, 1 /*locked*/, pr_idx);
|
||||||
|
if (pr_search_result) {
|
||||||
|
if (pagedresults_is_abandoned_or_notavailable(pb_conn, 1 /*locked*/, pr_idx)) {
|
||||||
|
@@ -705,7 +707,7 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
|
||||||
|
/* Previous operation was abandoned and the simplepaged object is not in use. */
|
||||||
|
send_ldap_result(pb, 0, NULL, "Simple Paged Results Search abandoned", 0, NULL);
|
||||||
|
rc = LDAP_SUCCESS;
|
||||||
|
- pthread_mutex_unlock(&(pb_conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pagedresults_mutex);
|
||||||
|
goto free_and_return;
|
||||||
|
} else {
|
||||||
|
slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_SET, pr_search_result);
|
||||||
|
@@ -719,7 +721,7 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
|
||||||
|
pr_stat = PAGEDRESULTS_SEARCH_END;
|
||||||
|
rc = LDAP_SUCCESS;
|
||||||
|
}
|
||||||
|
- pthread_mutex_unlock(&(pb_conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pagedresults_mutex);
|
||||||
|
pagedresults_unlock(pb_conn, pr_idx);
|
||||||
|
|
||||||
|
if ((PAGEDRESULTS_SEARCH_END == pr_stat) || (0 == pnentries)) {
|
||||||
|
@@ -844,10 +846,10 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
|
||||||
|
/* PAGED RESULTS */
|
||||||
|
if (op_is_pagedresults(operation)) {
|
||||||
|
/* cleanup the slot */
|
||||||
|
- pthread_mutex_lock(&(pb_conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pagedresults_mutex);
|
||||||
|
pagedresults_set_search_result(pb_conn, operation, NULL, 1, pr_idx);
|
||||||
|
rc = pagedresults_set_current_be(pb_conn, NULL, pr_idx, 1);
|
||||||
|
- pthread_mutex_unlock(&(pb_conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pagedresults_mutex);
|
||||||
|
}
|
||||||
|
if (1 == flag_no_such_object) {
|
||||||
|
break;
|
||||||
|
@@ -888,11 +890,11 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
|
||||||
|
slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET, &sr);
|
||||||
|
if ((PAGEDRESULTS_SEARCH_END == pr_stat) || (0 == pnentries)) {
|
||||||
|
/* no more entries, but at least another backend */
|
||||||
|
- pthread_mutex_lock(&(pb_conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pagedresults_mutex);
|
||||||
|
pagedresults_set_search_result(pb_conn, operation, NULL, 1, pr_idx);
|
||||||
|
be->be_search_results_release(&sr);
|
||||||
|
rc = pagedresults_set_current_be(pb_conn, next_be, pr_idx, 1);
|
||||||
|
- pthread_mutex_unlock(&(pb_conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pagedresults_mutex);
|
||||||
|
pr_stat = PAGEDRESULTS_SEARCH_END; /* make sure stat is SEARCH_END */
|
||||||
|
if (NULL == next_be) {
|
||||||
|
/* no more entries && no more backends */
|
||||||
|
@@ -920,9 +922,9 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
|
||||||
|
next_be = NULL; /* to break the loop */
|
||||||
|
if (operation->o_status & SLAPI_OP_STATUS_ABANDONED) {
|
||||||
|
/* It turned out this search was abandoned. */
|
||||||
|
- pthread_mutex_lock(&(pb_conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pagedresults_mutex);
|
||||||
|
pagedresults_free_one_msgid_nolock(pb_conn, operation->o_msgid);
|
||||||
|
- pthread_mutex_unlock(&(pb_conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pagedresults_mutex);
|
||||||
|
/* paged-results-request was abandoned; making an empty cookie. */
|
||||||
|
pagedresults_set_response_control(pb, 0, estimate, -1, pr_idx);
|
||||||
|
send_ldap_result(pb, 0, NULL, "Simple Paged Results Search abandoned", 0, NULL);
|
||||||
|
diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c
|
||||||
|
index e3444e944b..01fe3370f5 100644
|
||||||
|
--- a/ldap/servers/slapd/pagedresults.c
|
||||||
|
+++ b/ldap/servers/slapd/pagedresults.c
|
||||||
|
@@ -12,6 +12,34 @@
|
||||||
|
|
||||||
|
#include "slap.h"
|
||||||
|
|
||||||
|
+#define LOCK_HASH_SIZE 997 /* Should be a prime number */
|
||||||
|
+
|
||||||
|
+static pthread_mutex_t *lock_hash = NULL;
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+pageresult_lock_init()
|
||||||
|
+{
|
||||||
|
+ lock_hash = (pthread_mutex_t *)slapi_ch_calloc(LOCK_HASH_SIZE, sizeof(pthread_mutex_t));
|
||||||
|
+ for (size_t i=0; i<LOCK_HASH_SIZE; i++) {
|
||||||
|
+ pthread_mutex_init(&lock_hash[i], NULL);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+pageresult_lock_cleanup()
|
||||||
|
+{
|
||||||
|
+ for (size_t i=0; i<LOCK_HASH_SIZE; i++) {
|
||||||
|
+ pthread_mutex_destroy(&lock_hash[i]);
|
||||||
|
+ }
|
||||||
|
+ slapi_ch_free((void**)&lock_hash);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+pthread_mutex_t *
|
||||||
|
+pageresult_lock_get_addr(Connection *conn)
|
||||||
|
+{
|
||||||
|
+ return &lock_hash[(((size_t)conn)/sizeof (Connection))%LOCK_HASH_SIZE];
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* helper function to clean up one prp slot */
|
||||||
|
static void
|
||||||
|
_pr_cleanup_one_slot(PagedResults *prp)
|
||||||
|
@@ -98,7 +126,7 @@ pagedresults_parse_control_value(Slapi_PBlock *pb,
|
||||||
|
return LDAP_UNWILLING_TO_PERFORM;
|
||||||
|
}
|
||||||
|
|
||||||
|
- pthread_mutex_lock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pageresult_lock_get_addr(conn));
|
||||||
|
/* the ber encoding is no longer needed */
|
||||||
|
ber_free(ber, 1);
|
||||||
|
if (cookie.bv_len <= 0) {
|
||||||
|
@@ -206,7 +234,7 @@ pagedresults_parse_control_value(Slapi_PBlock *pb,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- pthread_mutex_unlock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pageresult_lock_get_addr(conn));
|
||||||
|
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE, "pagedresults_parse_control_value",
|
||||||
|
"<= idx %d\n", *index);
|
||||||
|
@@ -300,7 +328,7 @@ pagedresults_free_one(Connection *conn, Operation *op, int index)
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE, "pagedresults_free_one",
|
||||||
|
"=> idx=%d\n", index);
|
||||||
|
if (conn && (index > -1)) {
|
||||||
|
- pthread_mutex_lock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pageresult_lock_get_addr(conn));
|
||||||
|
if (conn->c_pagedresults.prl_count <= 0) {
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE, "pagedresults_free_one",
|
||||||
|
"conn=%" PRIu64 " paged requests list count is %d\n",
|
||||||
|
@@ -311,7 +339,7 @@ pagedresults_free_one(Connection *conn, Operation *op, int index)
|
||||||
|
conn->c_pagedresults.prl_count--;
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
- pthread_mutex_unlock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pageresult_lock_get_addr(conn));
|
||||||
|
}
|
||||||
|
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE, "pagedresults_free_one", "<= %d\n", rc);
|
||||||
|
@@ -319,7 +347,7 @@ pagedresults_free_one(Connection *conn, Operation *op, int index)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * Used for abandoning - conn->c_mutex is already locked in do_abandone.
|
||||||
|
+ * Used for abandoning - pageresult_lock_get_addr(conn) is already locked in do_abandone.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
pagedresults_free_one_msgid_nolock(Connection *conn, ber_int_t msgid)
|
||||||
|
@@ -363,11 +391,11 @@ pagedresults_get_current_be(Connection *conn, int index)
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
"pagedresults_get_current_be", "=> idx=%d\n", index);
|
||||||
|
if (conn && (index > -1)) {
|
||||||
|
- pthread_mutex_lock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pageresult_lock_get_addr(conn));
|
||||||
|
if (index < conn->c_pagedresults.prl_maxlen) {
|
||||||
|
be = conn->c_pagedresults.prl_list[index].pr_current_be;
|
||||||
|
}
|
||||||
|
- pthread_mutex_unlock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pageresult_lock_get_addr(conn));
|
||||||
|
}
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
"pagedresults_get_current_be", "<= %p\n", be);
|
||||||
|
@@ -382,13 +410,13 @@ pagedresults_set_current_be(Connection *conn, Slapi_Backend *be, int index, int
|
||||||
|
"pagedresults_set_current_be", "=> idx=%d\n", index);
|
||||||
|
if (conn && (index > -1)) {
|
||||||
|
if (!nolock)
|
||||||
|
- pthread_mutex_lock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pageresult_lock_get_addr(conn));
|
||||||
|
if (index < conn->c_pagedresults.prl_maxlen) {
|
||||||
|
conn->c_pagedresults.prl_list[index].pr_current_be = be;
|
||||||
|
}
|
||||||
|
rc = 0;
|
||||||
|
if (!nolock)
|
||||||
|
- pthread_mutex_unlock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pageresult_lock_get_addr(conn));
|
||||||
|
}
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
"pagedresults_set_current_be", "<= %d\n", rc);
|
||||||
|
@@ -407,13 +435,13 @@ pagedresults_get_search_result(Connection *conn, Operation *op, int locked, int
|
||||||
|
locked ? "locked" : "not locked", index);
|
||||||
|
if (conn && (index > -1)) {
|
||||||
|
if (!locked) {
|
||||||
|
- pthread_mutex_lock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pageresult_lock_get_addr(conn));
|
||||||
|
}
|
||||||
|
if (index < conn->c_pagedresults.prl_maxlen) {
|
||||||
|
sr = conn->c_pagedresults.prl_list[index].pr_search_result_set;
|
||||||
|
}
|
||||||
|
if (!locked) {
|
||||||
|
- pthread_mutex_unlock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pageresult_lock_get_addr(conn));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
@@ -433,7 +461,7 @@ pagedresults_set_search_result(Connection *conn, Operation *op, void *sr, int lo
|
||||||
|
index, sr);
|
||||||
|
if (conn && (index > -1)) {
|
||||||
|
if (!locked)
|
||||||
|
- pthread_mutex_lock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pageresult_lock_get_addr(conn));
|
||||||
|
if (index < conn->c_pagedresults.prl_maxlen) {
|
||||||
|
PagedResults *prp = conn->c_pagedresults.prl_list + index;
|
||||||
|
if (!(prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED) || !sr) {
|
||||||
|
@@ -443,7 +471,7 @@ pagedresults_set_search_result(Connection *conn, Operation *op, void *sr, int lo
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
if (!locked)
|
||||||
|
- pthread_mutex_unlock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pageresult_lock_get_addr(conn));
|
||||||
|
}
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
"pagedresults_set_search_result", "=> %d\n", rc);
|
||||||
|
@@ -460,11 +488,11 @@ pagedresults_get_search_result_count(Connection *conn, Operation *op, int index)
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
"pagedresults_get_search_result_count", "=> idx=%d\n", index);
|
||||||
|
if (conn && (index > -1)) {
|
||||||
|
- pthread_mutex_lock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pageresult_lock_get_addr(conn));
|
||||||
|
if (index < conn->c_pagedresults.prl_maxlen) {
|
||||||
|
count = conn->c_pagedresults.prl_list[index].pr_search_result_count;
|
||||||
|
}
|
||||||
|
- pthread_mutex_unlock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pageresult_lock_get_addr(conn));
|
||||||
|
}
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
"pagedresults_get_search_result_count", "<= %d\n", count);
|
||||||
|
@@ -481,11 +509,11 @@ pagedresults_set_search_result_count(Connection *conn, Operation *op, int count,
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
"pagedresults_set_search_result_count", "=> idx=%d\n", index);
|
||||||
|
if (conn && (index > -1)) {
|
||||||
|
- pthread_mutex_lock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pageresult_lock_get_addr(conn));
|
||||||
|
if (index < conn->c_pagedresults.prl_maxlen) {
|
||||||
|
conn->c_pagedresults.prl_list[index].pr_search_result_count = count;
|
||||||
|
}
|
||||||
|
- pthread_mutex_unlock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pageresult_lock_get_addr(conn));
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
@@ -506,11 +534,11 @@ pagedresults_get_search_result_set_size_estimate(Connection *conn,
|
||||||
|
"pagedresults_get_search_result_set_size_estimate",
|
||||||
|
"=> idx=%d\n", index);
|
||||||
|
if (conn && (index > -1)) {
|
||||||
|
- pthread_mutex_lock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pageresult_lock_get_addr(conn));
|
||||||
|
if (index < conn->c_pagedresults.prl_maxlen) {
|
||||||
|
count = conn->c_pagedresults.prl_list[index].pr_search_result_set_size_estimate;
|
||||||
|
}
|
||||||
|
- pthread_mutex_unlock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pageresult_lock_get_addr(conn));
|
||||||
|
}
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
"pagedresults_get_search_result_set_size_estimate", "<= %d\n",
|
||||||
|
@@ -532,11 +560,11 @@ pagedresults_set_search_result_set_size_estimate(Connection *conn,
|
||||||
|
"pagedresults_set_search_result_set_size_estimate",
|
||||||
|
"=> idx=%d\n", index);
|
||||||
|
if (conn && (index > -1)) {
|
||||||
|
- pthread_mutex_lock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pageresult_lock_get_addr(conn));
|
||||||
|
if (index < conn->c_pagedresults.prl_maxlen) {
|
||||||
|
conn->c_pagedresults.prl_list[index].pr_search_result_set_size_estimate = count;
|
||||||
|
}
|
||||||
|
- pthread_mutex_unlock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pageresult_lock_get_addr(conn));
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
@@ -555,11 +583,11 @@ pagedresults_get_with_sort(Connection *conn, Operation *op, int index)
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
"pagedresults_get_with_sort", "=> idx=%d\n", index);
|
||||||
|
if (conn && (index > -1)) {
|
||||||
|
- pthread_mutex_lock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pageresult_lock_get_addr(conn));
|
||||||
|
if (index < conn->c_pagedresults.prl_maxlen) {
|
||||||
|
flags = conn->c_pagedresults.prl_list[index].pr_flags & CONN_FLAG_PAGEDRESULTS_WITH_SORT;
|
||||||
|
}
|
||||||
|
- pthread_mutex_unlock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pageresult_lock_get_addr(conn));
|
||||||
|
}
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
"pagedresults_get_with_sort", "<= %d\n", flags);
|
||||||
|
@@ -576,14 +604,14 @@ pagedresults_set_with_sort(Connection *conn, Operation *op, int flags, int index
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
"pagedresults_set_with_sort", "=> idx=%d\n", index);
|
||||||
|
if (conn && (index > -1)) {
|
||||||
|
- pthread_mutex_lock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pageresult_lock_get_addr(conn));
|
||||||
|
if (index < conn->c_pagedresults.prl_maxlen) {
|
||||||
|
if (flags & OP_FLAG_SERVER_SIDE_SORTING) {
|
||||||
|
conn->c_pagedresults.prl_list[index].pr_flags |=
|
||||||
|
CONN_FLAG_PAGEDRESULTS_WITH_SORT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- pthread_mutex_unlock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pageresult_lock_get_addr(conn));
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE, "pagedresults_set_with_sort", "<= %d\n", rc);
|
||||||
|
@@ -600,11 +628,11 @@ pagedresults_get_unindexed(Connection *conn, Operation *op, int index)
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
"pagedresults_get_unindexed", "=> idx=%d\n", index);
|
||||||
|
if (conn && (index > -1)) {
|
||||||
|
- pthread_mutex_lock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pageresult_lock_get_addr(conn));
|
||||||
|
if (index < conn->c_pagedresults.prl_maxlen) {
|
||||||
|
flags = conn->c_pagedresults.prl_list[index].pr_flags & CONN_FLAG_PAGEDRESULTS_UNINDEXED;
|
||||||
|
}
|
||||||
|
- pthread_mutex_unlock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pageresult_lock_get_addr(conn));
|
||||||
|
}
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
"pagedresults_get_unindexed", "<= %d\n", flags);
|
||||||
|
@@ -621,12 +649,12 @@ pagedresults_set_unindexed(Connection *conn, Operation *op, int index)
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
"pagedresults_set_unindexed", "=> idx=%d\n", index);
|
||||||
|
if (conn && (index > -1)) {
|
||||||
|
- pthread_mutex_lock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pageresult_lock_get_addr(conn));
|
||||||
|
if (index < conn->c_pagedresults.prl_maxlen) {
|
||||||
|
conn->c_pagedresults.prl_list[index].pr_flags |=
|
||||||
|
CONN_FLAG_PAGEDRESULTS_UNINDEXED;
|
||||||
|
}
|
||||||
|
- pthread_mutex_unlock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pageresult_lock_get_addr(conn));
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
@@ -644,11 +672,11 @@ pagedresults_get_sort_result_code(Connection *conn, Operation *op, int index)
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
"pagedresults_get_sort_result_code", "=> idx=%d\n", index);
|
||||||
|
if (conn && (index > -1)) {
|
||||||
|
- pthread_mutex_lock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pageresult_lock_get_addr(conn));
|
||||||
|
if (index < conn->c_pagedresults.prl_maxlen) {
|
||||||
|
code = conn->c_pagedresults.prl_list[index].pr_sort_result_code;
|
||||||
|
}
|
||||||
|
- pthread_mutex_unlock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pageresult_lock_get_addr(conn));
|
||||||
|
}
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
"pagedresults_get_sort_result_code", "<= %d\n", code);
|
||||||
|
@@ -665,11 +693,11 @@ pagedresults_set_sort_result_code(Connection *conn, Operation *op, int code, int
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
"pagedresults_set_sort_result_code", "=> idx=%d\n", index);
|
||||||
|
if (conn && (index > -1)) {
|
||||||
|
- pthread_mutex_lock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pageresult_lock_get_addr(conn));
|
||||||
|
if (index < conn->c_pagedresults.prl_maxlen) {
|
||||||
|
conn->c_pagedresults.prl_list[index].pr_sort_result_code = code;
|
||||||
|
}
|
||||||
|
- pthread_mutex_unlock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pageresult_lock_get_addr(conn));
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
@@ -687,11 +715,11 @@ pagedresults_set_timelimit(Connection *conn, Operation *op, time_t timelimit, in
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
"pagedresults_set_timelimit", "=> idx=%d\n", index);
|
||||||
|
if (conn && (index > -1)) {
|
||||||
|
- pthread_mutex_lock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pageresult_lock_get_addr(conn));
|
||||||
|
if (index < conn->c_pagedresults.prl_maxlen) {
|
||||||
|
slapi_timespec_expire_at(timelimit, &(conn->c_pagedresults.prl_list[index].pr_timelimit_hr));
|
||||||
|
}
|
||||||
|
- pthread_mutex_unlock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pageresult_lock_get_addr(conn));
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE, "pagedresults_set_timelimit", "<= %d\n", rc);
|
||||||
|
@@ -746,7 +774,7 @@ pagedresults_cleanup(Connection *conn, int needlock)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needlock) {
|
||||||
|
- pthread_mutex_lock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pageresult_lock_get_addr(conn));
|
||||||
|
}
|
||||||
|
for (i = 0; conn->c_pagedresults.prl_list &&
|
||||||
|
i < conn->c_pagedresults.prl_maxlen;
|
||||||
|
@@ -765,7 +793,7 @@ pagedresults_cleanup(Connection *conn, int needlock)
|
||||||
|
}
|
||||||
|
conn->c_pagedresults.prl_count = 0;
|
||||||
|
if (needlock) {
|
||||||
|
- pthread_mutex_unlock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pageresult_lock_get_addr(conn));
|
||||||
|
}
|
||||||
|
/* slapi_log_err(SLAPI_LOG_TRACE, "pagedresults_cleanup", "<= %d\n", rc); */
|
||||||
|
return rc;
|
||||||
|
@@ -792,7 +820,7 @@ pagedresults_cleanup_all(Connection *conn, int needlock)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needlock) {
|
||||||
|
- pthread_mutex_lock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pageresult_lock_get_addr(conn));
|
||||||
|
}
|
||||||
|
for (i = 0; conn->c_pagedresults.prl_list &&
|
||||||
|
i < conn->c_pagedresults.prl_maxlen;
|
||||||
|
@@ -812,7 +840,7 @@ pagedresults_cleanup_all(Connection *conn, int needlock)
|
||||||
|
conn->c_pagedresults.prl_maxlen = 0;
|
||||||
|
conn->c_pagedresults.prl_count = 0;
|
||||||
|
if (needlock) {
|
||||||
|
- pthread_mutex_unlock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pageresult_lock_get_addr(conn));
|
||||||
|
}
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE, "pagedresults_cleanup_all", "<= %d\n", rc);
|
||||||
|
return rc;
|
||||||
|
@@ -831,7 +859,7 @@ pagedresults_check_or_set_processing(Connection *conn, int index)
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
"pagedresults_check_or_set_processing", "=>\n", index);
|
||||||
|
if (conn && (index > -1)) {
|
||||||
|
- pthread_mutex_lock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pageresult_lock_get_addr(conn));
|
||||||
|
if (index < conn->c_pagedresults.prl_maxlen) {
|
||||||
|
ret = (conn->c_pagedresults.prl_list[index].pr_flags &
|
||||||
|
CONN_FLAG_PAGEDRESULTS_PROCESSING);
|
||||||
|
@@ -839,7 +867,7 @@ pagedresults_check_or_set_processing(Connection *conn, int index)
|
||||||
|
conn->c_pagedresults.prl_list[index].pr_flags |=
|
||||||
|
CONN_FLAG_PAGEDRESULTS_PROCESSING;
|
||||||
|
}
|
||||||
|
- pthread_mutex_unlock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pageresult_lock_get_addr(conn));
|
||||||
|
}
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
"pagedresults_check_or_set_processing", "<= %d\n", ret);
|
||||||
|
@@ -858,7 +886,7 @@ pagedresults_reset_processing(Connection *conn, int index)
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
"pagedresults_reset_processing", "=> idx=%d\n", index);
|
||||||
|
if (conn && (index > -1)) {
|
||||||
|
- pthread_mutex_lock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pageresult_lock_get_addr(conn));
|
||||||
|
if (index < conn->c_pagedresults.prl_maxlen) {
|
||||||
|
ret = (conn->c_pagedresults.prl_list[index].pr_flags &
|
||||||
|
CONN_FLAG_PAGEDRESULTS_PROCESSING);
|
||||||
|
@@ -866,7 +894,7 @@ pagedresults_reset_processing(Connection *conn, int index)
|
||||||
|
conn->c_pagedresults.prl_list[index].pr_flags &=
|
||||||
|
~CONN_FLAG_PAGEDRESULTS_PROCESSING;
|
||||||
|
}
|
||||||
|
- pthread_mutex_unlock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pageresult_lock_get_addr(conn));
|
||||||
|
}
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
"pagedresults_reset_processing", "<= %d\n", ret);
|
||||||
|
@@ -885,7 +913,7 @@ pagedresults_reset_processing(Connection *conn, int index)
|
||||||
|
* Do not return timed out here. But let the next request take care the
|
||||||
|
* timedout slot(s).
|
||||||
|
*
|
||||||
|
- * must be called within conn->c_mutex
|
||||||
|
+ * must be called within pageresult_lock_get_addr(conn)
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
pagedresults_is_timedout_nolock(Connection *conn)
|
||||||
|
@@ -912,7 +940,7 @@ pagedresults_is_timedout_nolock(Connection *conn)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* reset all timeout
|
||||||
|
- * must be called within conn->c_mutex
|
||||||
|
+ * must be called within pageresult_lock_get_addr(conn)
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
pagedresults_reset_timedout_nolock(Connection *conn)
|
||||||
|
@@ -977,9 +1005,9 @@ pagedresults_lock(Connection *conn, int index)
|
||||||
|
if (!conn || (index < 0) || (index >= conn->c_pagedresults.prl_maxlen)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
- pthread_mutex_lock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pageresult_lock_get_addr(conn));
|
||||||
|
prp = conn->c_pagedresults.prl_list + index;
|
||||||
|
- pthread_mutex_unlock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pageresult_lock_get_addr(conn));
|
||||||
|
if (prp->pr_mutex) {
|
||||||
|
PR_Lock(prp->pr_mutex);
|
||||||
|
}
|
||||||
|
@@ -993,9 +1021,9 @@ pagedresults_unlock(Connection *conn, int index)
|
||||||
|
if (!conn || (index < 0) || (index >= conn->c_pagedresults.prl_maxlen)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
- pthread_mutex_lock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pageresult_lock_get_addr(conn));
|
||||||
|
prp = conn->c_pagedresults.prl_list + index;
|
||||||
|
- pthread_mutex_unlock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pageresult_lock_get_addr(conn));
|
||||||
|
if (prp->pr_mutex) {
|
||||||
|
PR_Unlock(prp->pr_mutex);
|
||||||
|
}
|
||||||
|
@@ -1010,11 +1038,11 @@ pagedresults_is_abandoned_or_notavailable(Connection *conn, int locked, int inde
|
||||||
|
return 1; /* not abandoned, but do not want to proceed paged results op. */
|
||||||
|
}
|
||||||
|
if (!locked) {
|
||||||
|
- pthread_mutex_lock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pageresult_lock_get_addr(conn));
|
||||||
|
}
|
||||||
|
prp = conn->c_pagedresults.prl_list + index;
|
||||||
|
if (!locked) {
|
||||||
|
- pthread_mutex_unlock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pageresult_lock_get_addr(conn));
|
||||||
|
}
|
||||||
|
return prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED;
|
||||||
|
}
|
||||||
|
@@ -1039,13 +1067,13 @@ pagedresults_set_search_result_pb(Slapi_PBlock *pb, void *sr, int locked)
|
||||||
|
"pagedresults_set_search_result_pb", "=> idx=%d, sr=%p\n", index, sr);
|
||||||
|
if (conn && (index > -1)) {
|
||||||
|
if (!locked)
|
||||||
|
- pthread_mutex_lock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_lock(pageresult_lock_get_addr(conn));
|
||||||
|
if (index < conn->c_pagedresults.prl_maxlen) {
|
||||||
|
conn->c_pagedresults.prl_list[index].pr_search_result_set = sr;
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
if (!locked) {
|
||||||
|
- pthread_mutex_unlock(&(conn->c_mutex));
|
||||||
|
+ pthread_mutex_unlock(pageresult_lock_get_addr(conn));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
slapi_log_err(SLAPI_LOG_TRACE,
|
||||||
|
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
|
||||||
|
index eba115a629..65efee8542 100644
|
||||||
|
--- a/ldap/servers/slapd/proto-slap.h
|
||||||
|
+++ b/ldap/servers/slapd/proto-slap.h
|
||||||
|
@@ -1547,6 +1547,9 @@ int slapd_do_all_nss_ssl_init(int slapd_exemode, int importexport_encrypt, int s
|
||||||
|
/*
|
||||||
|
* pagedresults.c
|
||||||
|
*/
|
||||||
|
+void pageresult_lock_init();
|
||||||
|
+void pageresult_lock_cleanup();
|
||||||
|
+pthread_mutex_t *pageresult_lock_get_addr(Connection *conn);
|
||||||
|
int pagedresults_parse_control_value(Slapi_PBlock *pb, struct berval *psbvp, ber_int_t *pagesize, int *index, Slapi_Backend *be);
|
||||||
|
void pagedresults_set_response_control(Slapi_PBlock *pb, int iscritical, ber_int_t estimate, int curr_search_count, int index);
|
||||||
|
Slapi_Backend *pagedresults_get_current_be(Connection *conn, int index);
|
111
SOURCES/Issue-5646-Various-memory-leaks-5725.patch
Normal file
111
SOURCES/Issue-5646-Various-memory-leaks-5725.patch
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
From 58d09ebe2498dfbbd7f20524a00f81b8cb6092f1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: James Chapman <jachapma@redhat.com>
|
||||||
|
Date: Mon, 29 May 2023 09:38:21 +0000
|
||||||
|
Subject: [PATCH] Issue 5646 - Various memory leaks (#5725)
|
||||||
|
|
||||||
|
Bug description: A memory leak occurs when a sync repl search is run
|
||||||
|
in refreshPersist mode. The connection from sync repl consumer is
|
||||||
|
closed without freeing up the ldap req ctrls.
|
||||||
|
|
||||||
|
Fix description: When the connection to the client is closed or on
|
||||||
|
shutdown free the request control structure if it exists.
|
||||||
|
|
||||||
|
relates: https://github.com/389ds/389-ds-base/issues/5646
|
||||||
|
|
||||||
|
Reviewed by: @progier389, @droideck, @Firstyear, @tbordaz (Thank you)
|
||||||
|
---
|
||||||
|
dirsrvtests/tests/suites/syncrepl_plugin/basic_test.py | 5 +----
|
||||||
|
ldap/servers/plugins/sync/sync_persist.c | 7 +++++++
|
||||||
|
ldap/servers/plugins/sync/sync_util.c | 4 ++++
|
||||||
|
3 files changed, 12 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dirsrvtests/tests/suites/syncrepl_plugin/basic_test.py b/dirsrvtests/tests/suites/syncrepl_plugin/basic_test.py
|
||||||
|
index 375517693a..eb3770b783 100644
|
||||||
|
--- a/dirsrvtests/tests/suites/syncrepl_plugin/basic_test.py
|
||||||
|
+++ b/dirsrvtests/tests/suites/syncrepl_plugin/basic_test.py
|
||||||
|
@@ -231,7 +231,7 @@ def run(self):
|
||||||
|
print('syncrepl_poll: LDAP error (%s)', e)
|
||||||
|
self.result = ldap_connection.get_cookies()
|
||||||
|
log.info("ZZZ result = %s" % self.result)
|
||||||
|
- self.conn.unbind()
|
||||||
|
+ ldap_connection.unbind()
|
||||||
|
|
||||||
|
def test_sync_repl_mep(topology, request):
|
||||||
|
"""Test sync repl with MEP plugin that triggers several
|
||||||
|
@@ -406,12 +406,10 @@ def test_sync_repl_cookie_add_del(topology, init_sync_repl_plugins, request):
|
||||||
|
6.: succeeds
|
||||||
|
"""
|
||||||
|
inst = topology[0]
|
||||||
|
-
|
||||||
|
# create a sync repl client and wait 5 seconds to be sure it is running
|
||||||
|
sync_repl = Sync_persist(inst)
|
||||||
|
sync_repl.start()
|
||||||
|
time.sleep(5)
|
||||||
|
-
|
||||||
|
# create users, that automember/memberof will generate nested updates
|
||||||
|
users = UserAccounts(inst, DEFAULT_SUFFIX)
|
||||||
|
users_set = []
|
||||||
|
@@ -427,7 +425,6 @@ def test_sync_repl_cookie_add_del(topology, init_sync_repl_plugins, request):
|
||||||
|
# and wait a bit to let sync_repl thread time to set its result before fetching it.
|
||||||
|
inst.stop()
|
||||||
|
cookies = sync_repl.get_result()
|
||||||
|
-
|
||||||
|
# checking that the cookie are in increasing and in an acceptable range (0..1000)
|
||||||
|
assert len(cookies) > 0
|
||||||
|
prev = -1
|
||||||
|
diff --git a/ldap/servers/plugins/sync/sync_persist.c b/ldap/servers/plugins/sync/sync_persist.c
|
||||||
|
index 12b23ebac3..d2210b64c9 100644
|
||||||
|
--- a/ldap/servers/plugins/sync/sync_persist.c
|
||||||
|
+++ b/ldap/servers/plugins/sync/sync_persist.c
|
||||||
|
@@ -903,6 +903,7 @@ sync_send_results(void *arg)
|
||||||
|
int conn_acq_flag = 0;
|
||||||
|
Slapi_Connection *conn = NULL;
|
||||||
|
Slapi_Operation *op = req->req_orig_op;
|
||||||
|
+ LDAPControl **ctrls = NULL;
|
||||||
|
int rc;
|
||||||
|
PRUint64 connid;
|
||||||
|
int opid;
|
||||||
|
@@ -1049,6 +1050,12 @@ sync_send_results(void *arg)
|
||||||
|
slapi_ch_free((void **)&strFilter);
|
||||||
|
slapi_pblock_set(req->req_pblock, SLAPI_SEARCH_STRFILTER, NULL);
|
||||||
|
|
||||||
|
+ slapi_pblock_get(req->req_pblock, SLAPI_REQCONTROLS, &ctrls);
|
||||||
|
+ if (ctrls) {
|
||||||
|
+ ldap_controls_free(ctrls);
|
||||||
|
+ slapi_pblock_set(req->req_pblock, SLAPI_REQCONTROLS, NULL);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
slapi_pblock_destroy(req->req_pblock);
|
||||||
|
req->req_pblock = NULL;
|
||||||
|
|
||||||
|
diff --git a/ldap/servers/plugins/sync/sync_util.c b/ldap/servers/plugins/sync/sync_util.c
|
||||||
|
index 21e1606312..605ddf1f36 100644
|
||||||
|
--- a/ldap/servers/plugins/sync/sync_util.c
|
||||||
|
+++ b/ldap/servers/plugins/sync/sync_util.c
|
||||||
|
@@ -689,6 +689,7 @@ sync_pblock_copy(Slapi_PBlock *src)
|
||||||
|
Slapi_Operation *operation;
|
||||||
|
Slapi_Operation *operation_new;
|
||||||
|
Slapi_Connection *connection;
|
||||||
|
+ LDAPControl **ctrls = NULL;
|
||||||
|
int *scope;
|
||||||
|
int *deref;
|
||||||
|
int *filter_normalized;
|
||||||
|
@@ -715,8 +716,10 @@ sync_pblock_copy(Slapi_PBlock *src)
|
||||||
|
slapi_pblock_get(src, SLAPI_REQUESTOR_ISROOT, &isroot);
|
||||||
|
slapi_pblock_get(src, SLAPI_SEARCH_SIZELIMIT, &sizelimit);
|
||||||
|
slapi_pblock_get(src, SLAPI_SEARCH_TIMELIMIT, &timelimit);
|
||||||
|
+ slapi_pblock_get(src, SLAPI_REQCONTROLS, &ctrls);
|
||||||
|
slapi_pblock_get(src, SLAPI_PLUGIN, &pi);
|
||||||
|
|
||||||
|
+
|
||||||
|
Slapi_PBlock *dest = slapi_pblock_new();
|
||||||
|
operation_new = slapi_operation_new(0);
|
||||||
|
msgid = slapi_operation_get_msgid(operation);
|
||||||
|
@@ -737,6 +740,7 @@ sync_pblock_copy(Slapi_PBlock *src)
|
||||||
|
slapi_pblock_set(dest, SLAPI_REQUESTOR_ISROOT, &isroot);
|
||||||
|
slapi_pblock_set(dest, SLAPI_SEARCH_SIZELIMIT, &sizelimit);
|
||||||
|
slapi_pblock_set(dest, SLAPI_SEARCH_TIMELIMIT, &timelimit);
|
||||||
|
+ slapi_pblock_set(dest, SLAPI_REQCONTROLS, ctrls);
|
||||||
|
slapi_pblock_set(dest, SLAPI_PLUGIN, pi);
|
||||||
|
|
||||||
|
return dest;
|
259
SOURCES/Issue-5789-Improve-ds-replcheck-error-handling.patch
Normal file
259
SOURCES/Issue-5789-Improve-ds-replcheck-error-handling.patch
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
From 4c16b43c714b0b3d1d7ba6cb65be00bd42a27f3f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mark Reynolds <mreynolds@redhat.com>
|
||||||
|
Date: Tue, 6 Jun 2023 12:49:50 -0400
|
||||||
|
Subject: [PATCH] Issue 5789 - Improve ds-replcheck error handling
|
||||||
|
|
||||||
|
Description: When replication is not fully configured the tool outputs vague
|
||||||
|
messages. These should be cleaned up to indicate that
|
||||||
|
replication was not initialized. Also added healthcheck.
|
||||||
|
|
||||||
|
Relates: https://github.com/389ds/389-ds-base/issues/5789
|
||||||
|
|
||||||
|
Reviewed by: tbordaz, spichugi, progier (Thanks!!!)
|
||||||
|
---
|
||||||
|
ldap/admin/src/scripts/ds-replcheck | 35 +++++++++++--------
|
||||||
|
.../src/lib/replication/replTasks.jsx | 2 +-
|
||||||
|
src/cockpit/389-console/src/replication.jsx | 3 +-
|
||||||
|
src/lib389/lib389/cli_conf/replication.py | 7 +++-
|
||||||
|
src/lib389/lib389/config.py | 2 +-
|
||||||
|
src/lib389/lib389/lint.py | 10 ++++++
|
||||||
|
src/lib389/lib389/replica.py | 20 +++++++++--
|
||||||
|
7 files changed, 58 insertions(+), 21 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ldap/admin/src/scripts/ds-replcheck b/ldap/admin/src/scripts/ds-replcheck
|
||||||
|
index f411f357aa..efa13ffe81 100755
|
||||||
|
--- a/ldap/admin/src/scripts/ds-replcheck
|
||||||
|
+++ b/ldap/admin/src/scripts/ds-replcheck
|
||||||
|
@@ -1,7 +1,7 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
# --- BEGIN COPYRIGHT BLOCK ---
|
||||||
|
-# Copyright (C) 2021 Red Hat, Inc.
|
||||||
|
+# Copyright (C) 2023 Red Hat, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# License: GPL (version 3 or any later version).
|
||||||
|
@@ -216,17 +216,17 @@ def get_ruv_state(opts):
|
||||||
|
mtime = get_ruv_time(opts['supplier_ruv'], opts['rid'])
|
||||||
|
rtime = get_ruv_time(opts['replica_ruv'], opts['rid'])
|
||||||
|
if mtime == -1:
|
||||||
|
- repl_state = "Replication State: Replica ID ({}) not found in Supplier's RUV".format(opts['rid'])
|
||||||
|
+ repl_state = f"Replication State: Replica ID ({opts['rid']}) not found in Supplier's RUV"
|
||||||
|
elif rtime == -1:
|
||||||
|
- repl_state = "Replication State: Replica ID ({}) not found in Replica's RUV (not initialized?)".format(opts['rid'])
|
||||||
|
+ repl_state = f"Replication State: Replica ID ({opts['rid']}) not found in Replica's RUV (not initialized?)"
|
||||||
|
elif mtime == 0:
|
||||||
|
repl_state = "Replication State: Supplier has not seen any updates"
|
||||||
|
elif rtime == 0:
|
||||||
|
repl_state = "Replication State: Replica has not seen any changes from the Supplier"
|
||||||
|
elif mtime > rtime:
|
||||||
|
- repl_state = "Replication State: Replica is behind Supplier by: {} seconds".format(mtime - rtime)
|
||||||
|
+ repl_state = f"Replication State: Replica is behind Supplier by: {mtime - rtime} seconds"
|
||||||
|
elif mtime < rtime:
|
||||||
|
- repl_state = "Replication State: Replica is ahead of Supplier by: {} seconds".format(rtime - mtime)
|
||||||
|
+ repl_state = f"Replication State: Replica is ahead of Supplier by: {rtime - mtime} seconds"
|
||||||
|
else:
|
||||||
|
repl_state = "Replication State: Supplier and Replica are in perfect synchronization"
|
||||||
|
|
||||||
|
@@ -928,7 +928,7 @@ def check_for_diffs(mentries, mglue, rentries, rglue, report, opts):
|
||||||
|
|
||||||
|
return report
|
||||||
|
|
||||||
|
-def validate_suffix(ldapnode, suffix, hostname):
|
||||||
|
+def validate_suffix(ldapnode, suffix, hostname, port):
|
||||||
|
"""Validate that the suffix exists
|
||||||
|
:param ldapnode - The LDAP object
|
||||||
|
:param suffix - The suffix to validate
|
||||||
|
@@ -938,10 +938,11 @@ def validate_suffix(ldapnode, suffix, hostname):
|
||||||
|
try:
|
||||||
|
ldapnode.search_s(suffix, ldap.SCOPE_BASE)
|
||||||
|
except ldap.NO_SUCH_OBJECT:
|
||||||
|
- print("Error: Failed to validate suffix in {}. {} does not exist.".format(hostname, suffix))
|
||||||
|
+ print(f"Error: Failed to validate suffix in {hostname}:{port}. {suffix} " +
|
||||||
|
+ "does not exist. Replica might need to be initialized.")
|
||||||
|
return False
|
||||||
|
except ldap.LDAPError as e:
|
||||||
|
- print("Error: failed to validate suffix in {} ({}). ".format(hostname, str(e)))
|
||||||
|
+ print(f"Error: failed to validate suffix in {hostname}:{port} ({str(e)}). ")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Check suffix is replicated
|
||||||
|
@@ -949,10 +950,10 @@ def validate_suffix(ldapnode, suffix, hostname):
|
||||||
|
replica_filter = "(&(objectclass=nsds5replica)(nsDS5ReplicaRoot=%s))" % suffix
|
||||||
|
supplier_replica = ldapnode.search_s("cn=config",ldap.SCOPE_SUBTREE,replica_filter)
|
||||||
|
if (len(supplier_replica) != 1):
|
||||||
|
- print("Error: Failed to validate suffix in {}. {} is not replicated.".format(hostname, suffix))
|
||||||
|
+ print(f"Error: Failed to validate suffix in {hostname}:{port}. {suffix} is not replicated.")
|
||||||
|
return False
|
||||||
|
except ldap.LDAPError as e:
|
||||||
|
- print("Error: failed to validate suffix in {} ({}). ".format(hostname, str(e)))
|
||||||
|
+ print(f"Error: failed to validate suffix in {hostname}:{port} ({str(e)}). ")
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
@@ -1034,10 +1035,10 @@ def connect_to_replicas(opts):
|
||||||
|
# Validate suffix
|
||||||
|
if opts['verbose']:
|
||||||
|
print ("Validating suffix ...")
|
||||||
|
- if not validate_suffix(supplier, opts['suffix'], opts['mhost']):
|
||||||
|
+ if not validate_suffix(supplier, opts['suffix'], opts['mhost'], opts['mport']):
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
- if not validate_suffix(replica,opts['suffix'], opts['rhost']):
|
||||||
|
+ if not validate_suffix(replica,opts['suffix'], opts['rhost'], opts['rport']):
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Get the RUVs
|
||||||
|
@@ -1048,8 +1049,11 @@ def connect_to_replicas(opts):
|
||||||
|
if len(supplier_ruv) > 0:
|
||||||
|
opts['supplier_ruv'] = ensure_list_str(supplier_ruv[0][1]['nsds50ruv'])
|
||||||
|
else:
|
||||||
|
- print("Error: Supplier does not have an RUV entry")
|
||||||
|
+ print("Error: Supplier does not have an RUV entry. It might need to be initialized.")
|
||||||
|
sys.exit(1)
|
||||||
|
+ except ldap.NO_SUCH_OBJECT:
|
||||||
|
+ print("Error: Supplier does not have an RUV entry. It might need to be initialized.")
|
||||||
|
+ sys.exit(1)
|
||||||
|
except ldap.LDAPError as e:
|
||||||
|
print("Error: Failed to get Supplier RUV entry: {}".format(str(e)))
|
||||||
|
sys.exit(1)
|
||||||
|
@@ -1061,8 +1065,11 @@ def connect_to_replicas(opts):
|
||||||
|
if len(replica_ruv) > 0:
|
||||||
|
opts['replica_ruv'] = ensure_list_str(replica_ruv[0][1]['nsds50ruv'])
|
||||||
|
else:
|
||||||
|
- print("Error: Replica does not have an RUV entry")
|
||||||
|
+ print("Error: Replica does not have an RUV entry. It might need to be initialized.")
|
||||||
|
sys.exit(1)
|
||||||
|
+ except ldap.NO_SUCH_OBJECT:
|
||||||
|
+ print("Error: Replica does not have an RUV entry. It might need to be initialized.")
|
||||||
|
+ sys.exit(1)
|
||||||
|
except ldap.LDAPError as e:
|
||||||
|
print("Error: Failed to get Replica RUV entry: {}".format(str(e)))
|
||||||
|
sys.exit(1)
|
||||||
|
diff --git a/src/cockpit/389-console/src/lib/replication/replTasks.jsx b/src/cockpit/389-console/src/lib/replication/replTasks.jsx
|
||||||
|
index 9387af3258..d592995f88 100644
|
||||||
|
--- a/src/cockpit/389-console/src/lib/replication/replTasks.jsx
|
||||||
|
+++ b/src/cockpit/389-console/src/lib/replication/replTasks.jsx
|
||||||
|
@@ -345,7 +345,7 @@ export class ReplRUV extends React.Component {
|
||||||
|
|
||||||
|
if (localRID == "") {
|
||||||
|
localRUV =
|
||||||
|
- <div className="ds-indent">
|
||||||
|
+ <div className="ds-indent ds-margin-top">
|
||||||
|
<i>
|
||||||
|
There is no local RUV, the database might not have been initialized yet.
|
||||||
|
</i>
|
||||||
|
diff --git a/src/cockpit/389-console/src/replication.jsx b/src/cockpit/389-console/src/replication.jsx
|
||||||
|
index c2598c1181..76b8da486a 100644
|
||||||
|
--- a/src/cockpit/389-console/src/replication.jsx
|
||||||
|
+++ b/src/cockpit/389-console/src/replication.jsx
|
||||||
|
@@ -880,7 +880,8 @@ export class Replication extends React.Component {
|
||||||
|
})
|
||||||
|
.fail(err => {
|
||||||
|
const errMsg = JSON.parse(err);
|
||||||
|
- if (errMsg.desc !== "No such object") {
|
||||||
|
+ if (errMsg.desc !== "No such object" &&
|
||||||
|
+ !errMsg.desc.includes('There is no RUV for suffix')) {
|
||||||
|
this.props.addNotification(
|
||||||
|
"error",
|
||||||
|
`Error loading suffix RUV - ${errMsg.desc}`
|
||||||
|
diff --git a/src/lib389/lib389/cli_conf/replication.py b/src/lib389/lib389/cli_conf/replication.py
|
||||||
|
index 8a919da989..2c9501cdef 100644
|
||||||
|
--- a/src/lib389/lib389/cli_conf/replication.py
|
||||||
|
+++ b/src/lib389/lib389/cli_conf/replication.py
|
||||||
|
@@ -115,10 +115,15 @@ def _args_to_attrs(args):
|
||||||
|
#
|
||||||
|
def get_ruv(inst, basedn, log, args):
|
||||||
|
replicas = Replicas(inst)
|
||||||
|
- replica = replicas.get(args.suffix)
|
||||||
|
+ try:
|
||||||
|
+ replica = replicas.get(args.suffix)
|
||||||
|
+ except ldap.NO_SUCH_OBJECT:
|
||||||
|
+ raise ValueError(f"Suffix '{args.suffix}' is not configured for replication.")
|
||||||
|
ruv = replica.get_ruv()
|
||||||
|
ruv_dict = ruv.format_ruv()
|
||||||
|
ruvs = ruv_dict['ruvs']
|
||||||
|
+ if len(ruvs) == 0:
|
||||||
|
+ raise ValueError(f"There is no RUV for suffix {args.suffix}. Replica is not initialized.")
|
||||||
|
if args and args.json:
|
||||||
|
log.info(json.dumps({"type": "list", "items": ruvs}, indent=4))
|
||||||
|
else:
|
||||||
|
diff --git a/src/lib389/lib389/config.py b/src/lib389/lib389/config.py
|
||||||
|
index c178eb02f0..00d38463a0 100644
|
||||||
|
--- a/src/lib389/lib389/config.py
|
||||||
|
+++ b/src/lib389/lib389/config.py
|
||||||
|
@@ -209,7 +209,7 @@ def _lint_hr_timestamp(self):
|
||||||
|
yield report
|
||||||
|
|
||||||
|
def _lint_passwordscheme(self):
|
||||||
|
- allowed_schemes = ['SSHA512', 'PBKDF2_SHA256', 'GOST_YESCRYPT']
|
||||||
|
+ allowed_schemes = ['PBKDF2-SHA512', 'PBKDF2_SHA256', 'PBKDF2_SHA512', 'GOST_YESCRYPT']
|
||||||
|
u_password_scheme = self.get_attr_val_utf8('passwordStorageScheme')
|
||||||
|
u_root_scheme = self.get_attr_val_utf8('nsslapd-rootpwstoragescheme')
|
||||||
|
if u_root_scheme not in allowed_schemes or u_password_scheme not in allowed_schemes:
|
||||||
|
diff --git a/src/lib389/lib389/lint.py b/src/lib389/lib389/lint.py
|
||||||
|
index ce23d5c128..0219801f48 100644
|
||||||
|
--- a/src/lib389/lib389/lint.py
|
||||||
|
+++ b/src/lib389/lib389/lint.py
|
||||||
|
@@ -310,6 +310,16 @@
|
||||||
|
'fix': """Check if the consumer is running, and also check the errors log for more information."""
|
||||||
|
}
|
||||||
|
|
||||||
|
+DSREPLLE0006 = {
|
||||||
|
+ 'dsle': 'DSREPLLE0006',
|
||||||
|
+ 'severity': 'MEDIUM',
|
||||||
|
+ 'description': 'Replication has not been initilaized',
|
||||||
|
+ 'items': ['Replication'],
|
||||||
|
+ 'detail': """The replication for "SUFFIX" does not appear to be initialzied,
|
||||||
|
+because there is no RUV found for the suffix.""",
|
||||||
|
+ 'fix': """Initialize this replica from a primary supplier replica"""
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
# Replication changelog
|
||||||
|
DSCLLE0001 = {
|
||||||
|
'dsle': 'DSCLLE0001',
|
||||||
|
diff --git a/src/lib389/lib389/replica.py b/src/lib389/lib389/replica.py
|
||||||
|
index f0c71cbebd..8b02433454 100644
|
||||||
|
--- a/src/lib389/lib389/replica.py
|
||||||
|
+++ b/src/lib389/lib389/replica.py
|
||||||
|
@@ -45,7 +45,7 @@
|
||||||
|
from lib389.idm.organizationalunit import OrganizationalUnits
|
||||||
|
from lib389.conflicts import ConflictEntries
|
||||||
|
from lib389.lint import (DSREPLLE0001, DSREPLLE0002, DSREPLLE0003, DSREPLLE0004,
|
||||||
|
- DSREPLLE0005, DSCLLE0001)
|
||||||
|
+ DSREPLLE0005, DSREPLLE0006, DSCLLE0001)
|
||||||
|
|
||||||
|
|
||||||
|
class ReplicaLegacy(object):
|
||||||
|
@@ -1207,6 +1207,20 @@ def _lint_conflicts(self):
|
||||||
|
report['check'] = f'replication:conflicts'
|
||||||
|
yield report
|
||||||
|
|
||||||
|
+ def _lint_no_ruv(self):
|
||||||
|
+ # No RUV means replica has not been initialized
|
||||||
|
+ replicas = Replicas(self._instance).list()
|
||||||
|
+ for replica in replicas:
|
||||||
|
+ ruv = replica.get_ruv()
|
||||||
|
+ ruv_dict = ruv.format_ruv()
|
||||||
|
+ ruvs = ruv_dict['ruvs']
|
||||||
|
+ suffix = replica.get_suffix()
|
||||||
|
+ if len(ruvs) == 0:
|
||||||
|
+ report = copy.deepcopy(DSREPLLE0006)
|
||||||
|
+ report['detail'] = report['detail'].replace('SUFFIX', suffix)
|
||||||
|
+ report['check'] = 'replication'
|
||||||
|
+ yield report
|
||||||
|
+
|
||||||
|
def _validate(self, rdn, properties, basedn):
|
||||||
|
(tdn, str_props) = super(Replica, self)._validate(rdn, properties, basedn)
|
||||||
|
# We override the tdn here. We use the MT for the suffix.
|
||||||
|
@@ -1587,8 +1601,8 @@ def get_ruv(self):
|
||||||
|
serverctrls=self._server_controls, clientctrls=self._client_controls,
|
||||||
|
escapehatch='i am sure')[0]
|
||||||
|
data = ensure_list_str(ent.getValues('nsds50ruv'))
|
||||||
|
- except IndexError:
|
||||||
|
- # There is no ruv entry, it's okay
|
||||||
|
+ except (IndexError, ldap.NO_SUCH_OBJECT):
|
||||||
|
+ # There are no ruv elements, it's okay
|
||||||
|
pass
|
||||||
|
|
||||||
|
return RUV(data)
|
@ -0,0 +1,514 @@
|
|||||||
|
From 231f92a551246aea637952f9f7f75c6d61540e80 Mon Sep 17 00:00:00 2001
|
||||||
|
From: James Chapman <jachapma@redhat.com>
|
||||||
|
Date: Thu, 20 Jul 2023 15:47:14 +0000
|
||||||
|
Subject: [PATCH] Issue 5804 - dtablesize being set to soft maxfiledescriptor
|
||||||
|
limit (#5806)
|
||||||
|
|
||||||
|
Bug Description: 389ds is not setting dtablesize properly based when systemd is setting
|
||||||
|
the maxfiledescriptors with it's default settings. dtablesize stays 1024 which causes
|
||||||
|
massive slowdown once you hit around 950 connection
|
||||||
|
|
||||||
|
Fix Description: dtablesize is set to the connection table size, this
|
||||||
|
commit sets the connection table size/dtablesize to the system max
|
||||||
|
file descriptor number less the reserve file descriptors.
|
||||||
|
|
||||||
|
relates: https://github.com/389ds/389-ds-base/issues/5804
|
||||||
|
|
||||||
|
Reviewed by: @tbordaz @progier389 (Thank you)
|
||||||
|
---
|
||||||
|
.../suites/resource_limits/fdlimits_test.py | 47 +++-
|
||||||
|
ldap/servers/slapd/conntable.c | 2 +
|
||||||
|
ldap/servers/slapd/daemon.c | 37 ++-
|
||||||
|
ldap/servers/slapd/libglobs.c | 257 ++++++++++++++----
|
||||||
|
ldap/servers/slapd/proto-slap.h | 6 +-
|
||||||
|
5 files changed, 283 insertions(+), 66 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dirsrvtests/tests/suites/resource_limits/fdlimits_test.py b/dirsrvtests/tests/suites/resource_limits/fdlimits_test.py
|
||||||
|
index 3b26e8cae6..19854b01d5 100644
|
||||||
|
--- a/dirsrvtests/tests/suites/resource_limits/fdlimits_test.py
|
||||||
|
+++ b/dirsrvtests/tests/suites/resource_limits/fdlimits_test.py
|
||||||
|
@@ -11,6 +11,7 @@
|
||||||
|
import os
|
||||||
|
import ldap
|
||||||
|
import resource
|
||||||
|
+from lib389.backend import Backends
|
||||||
|
from lib389._constants import *
|
||||||
|
from lib389.topologies import topology_st
|
||||||
|
from lib389.utils import ds_is_older, ensure_str
|
||||||
|
@@ -22,9 +23,11 @@
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
FD_ATTR = "nsslapd-maxdescriptors"
|
||||||
|
+RESRV_FD_ATTR = "nsslapd-reservedescriptors"
|
||||||
|
GLOBAL_LIMIT = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
|
||||||
|
SYSTEMD_LIMIT = ensure_str(check_output("systemctl show -p LimitNOFILE dirsrv@standalone1".split(" ")).strip()).split('=')[1]
|
||||||
|
CUSTOM_VAL = str(int(SYSTEMD_LIMIT) - 10)
|
||||||
|
+RESRV_DESC_VAL = str(10)
|
||||||
|
TOO_HIGH_VAL = str(GLOBAL_LIMIT * 2)
|
||||||
|
TOO_HIGH_VAL2 = str(int(SYSTEMD_LIMIT) * 2)
|
||||||
|
TOO_LOW_VAL = "0"
|
||||||
|
@@ -74,7 +77,49 @@ def test_fd_limits(topology_st):
|
||||||
|
max_fd = topology_st.standalone.config.get_attr_val_utf8(FD_ATTR)
|
||||||
|
assert max_fd == CUSTOM_VAL
|
||||||
|
|
||||||
|
- log.info("Test PASSED")
|
||||||
|
+ log.info("test_fd_limits PASSED")
|
||||||
|
+
|
||||||
|
+@pytest.mark.skipif(ds_is_older("1.4.1.2"), reason="Not implemented")
|
||||||
|
+def test_reserve_descriptor_validation(topology_st):
|
||||||
|
+ """Test the reserve descriptor self check
|
||||||
|
+
|
||||||
|
+ :id: TODO
|
||||||
|
+ :setup: Standalone Instance
|
||||||
|
+ :steps:
|
||||||
|
+ 1. Set attr nsslapd-reservedescriptors to a low value of RESRV_DESC_VAL (10)
|
||||||
|
+ 2. Verify low value has been set
|
||||||
|
+ 3. Restart instance (On restart the reservedescriptor attr will be validated)
|
||||||
|
+ 4. Check updated value for nsslapd-reservedescriptors attr
|
||||||
|
+ :expectedresults:
|
||||||
|
+ 1. Success
|
||||||
|
+ 2. A value of RESRV_DESC_VAL (10) is returned
|
||||||
|
+ 3. Success
|
||||||
|
+ 4. A value of STANDALONE_INST_RESRV_DESCS (55) is returned
|
||||||
|
+ """
|
||||||
|
+
|
||||||
|
+ # Set nsslapd-reservedescriptors to a low value (RESRV_DESC_VAL:10)
|
||||||
|
+ topology_st.standalone.config.set(RESRV_FD_ATTR, RESRV_DESC_VAL)
|
||||||
|
+ resrv_fd = topology_st.standalone.config.get_attr_val_utf8(RESRV_FD_ATTR)
|
||||||
|
+ assert resrv_fd == RESRV_DESC_VAL
|
||||||
|
+
|
||||||
|
+ # An instance restart triggers a validation of the configured nsslapd-reservedescriptors attribute
|
||||||
|
+ topology_st.standalone.restart()
|
||||||
|
+
|
||||||
|
+ """
|
||||||
|
+ A standalone instance contains a single backend with default indexes
|
||||||
|
+ so we only check these. TODO add tests for repl, chaining, PTA, SSL
|
||||||
|
+ """
|
||||||
|
+ STANDALONE_INST_RESRV_DESCS = 20 # 20 = Reserve descriptor constant
|
||||||
|
+ backends = Backends(topology_st.standalone)
|
||||||
|
+ STANDALONE_INST_RESRV_DESCS += (len(backends.list()) * 4) # 4 = Backend descriptor constant
|
||||||
|
+ for be in backends.list() :
|
||||||
|
+ STANDALONE_INST_RESRV_DESCS += len(be.get_indexes().list())
|
||||||
|
+
|
||||||
|
+ # Varify reservedescriptors has been updated
|
||||||
|
+ resrv_fd = topology_st.standalone.config.get_attr_val_utf8(RESRV_FD_ATTR)
|
||||||
|
+ assert resrv_fd == str(STANDALONE_INST_RESRV_DESCS)
|
||||||
|
+
|
||||||
|
+ log.info("test_reserve_descriptor_validation PASSED")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
diff --git a/ldap/servers/slapd/conntable.c b/ldap/servers/slapd/conntable.c
|
||||||
|
index feb9c0d756..5e6513880f 100644
|
||||||
|
--- a/ldap/servers/slapd/conntable.c
|
||||||
|
+++ b/ldap/servers/slapd/conntable.c
|
||||||
|
@@ -138,6 +138,8 @@ connection_table_new(int table_size)
|
||||||
|
ct->conn_next_offset = 1;
|
||||||
|
ct->conn_free_offset = 1;
|
||||||
|
|
||||||
|
+ slapi_log_err(SLAPI_LOG_INFO, "connection_table_new", "conntablesize:%d\n", ct->size);
|
||||||
|
+
|
||||||
|
pthread_mutexattr_t monitor_attr = {0};
|
||||||
|
pthread_mutexattr_init(&monitor_attr);
|
||||||
|
pthread_mutexattr_settype(&monitor_attr, PTHREAD_MUTEX_RECURSIVE);
|
||||||
|
diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
|
||||||
|
index 388fa09431..e5b7d6e06a 100644
|
||||||
|
--- a/ldap/servers/slapd/daemon.c
|
||||||
|
+++ b/ldap/servers/slapd/daemon.c
|
||||||
|
@@ -82,6 +82,7 @@ PRFileDesc *signalpipe[2];
|
||||||
|
static int writesignalpipe = SLAPD_INVALID_SOCKET;
|
||||||
|
static int readsignalpipe = SLAPD_INVALID_SOCKET;
|
||||||
|
#define FDS_SIGNAL_PIPE 0
|
||||||
|
+#define MAX_LDAP_CONNS 64000
|
||||||
|
|
||||||
|
static PRThread *accept_thread_p = NULL;
|
||||||
|
static PRThread *disk_thread_p = NULL;
|
||||||
|
@@ -107,7 +108,7 @@ static PRFileDesc *tls_listener = NULL; /* Stashed tls listener for get_ssl_list
|
||||||
|
|
||||||
|
#define SLAPD_POLL_LISTEN_READY(xxflagsxx) (xxflagsxx & PR_POLL_READ)
|
||||||
|
|
||||||
|
-static int get_configured_connection_table_size(void);
|
||||||
|
+static int get_connection_table_size(void);
|
||||||
|
#ifdef RESOLVER_NEEDS_LOW_FILE_DESCRIPTORS
|
||||||
|
static void get_loopback_by_addr(void);
|
||||||
|
#endif
|
||||||
|
@@ -1063,7 +1064,11 @@ slapd_daemon(daemon_ports_t *ports)
|
||||||
|
PRIntervalTime pr_timeout = PR_MillisecondsToInterval(slapd_wakeup_timer);
|
||||||
|
uint64_t threads;
|
||||||
|
int in_referral_mode = config_check_referral_mode();
|
||||||
|
- int connection_table_size = get_configured_connection_table_size();
|
||||||
|
+ int connection_table_size = get_connection_table_size();
|
||||||
|
+ if (!connection_table_size) {
|
||||||
|
+ slapi_log_err(SLAPI_LOG_ERR, "slapd_daemon", "Not enough available file descriuptors");
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
the_connection_table = connection_table_new(connection_table_size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -2846,18 +2851,32 @@ catch_signals()
|
||||||
|
#endif /* HPUX */
|
||||||
|
|
||||||
|
static int
|
||||||
|
-get_configured_connection_table_size(void)
|
||||||
|
+get_connection_table_size(void)
|
||||||
|
{
|
||||||
|
- int size = config_get_conntablesize();
|
||||||
|
+ int size = 0;
|
||||||
|
+ int resrvdesc = 0;
|
||||||
|
int maxdesc = config_get_maxdescriptors();
|
||||||
|
|
||||||
|
- /*
|
||||||
|
- * Cap the table size at nsslapd-maxdescriptors.
|
||||||
|
- */
|
||||||
|
- if (maxdesc >= 0 && size > maxdesc) {
|
||||||
|
- size = maxdesc;
|
||||||
|
+ /* Validate configured reserve descriptors */
|
||||||
|
+ validate_num_config_reservedescriptors();
|
||||||
|
+
|
||||||
|
+ resrvdesc = config_get_reservedescriptors();
|
||||||
|
+ if (maxdesc > resrvdesc) {
|
||||||
|
+ size = (maxdesc - resrvdesc);
|
||||||
|
+ } else {
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Verify size does not exceed max num of conns */
|
||||||
|
+ if (size > MAX_LDAP_CONNS) {
|
||||||
|
+ size = MAX_LDAP_CONNS;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
|
||||||
|
+ CFG_LOCK_WRITE(slapdFrontendConfig);
|
||||||
|
+ slapdFrontendConfig->conntablesize = size;
|
||||||
|
+ CFG_UNLOCK_WRITE(slapdFrontendConfig);
|
||||||
|
+
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
|
||||||
|
index f6c6b52a1a..43f924947b 100644
|
||||||
|
--- a/ldap/servers/slapd/libglobs.c
|
||||||
|
+++ b/ldap/servers/slapd/libglobs.c
|
||||||
|
@@ -1670,13 +1670,6 @@ FrontendConfig_init(void)
|
||||||
|
cfg->groupevalnestlevel = SLAPD_DEFAULT_GROUPEVALNESTLEVEL;
|
||||||
|
cfg->snmp_index = SLAPD_DEFAULT_SNMP_INDEX;
|
||||||
|
cfg->SSLclientAuth = SLAPD_DEFAULT_SSLCLIENTAUTH;
|
||||||
|
-
|
||||||
|
-#ifdef USE_SYSCONF
|
||||||
|
- cfg->conntablesize = sysconf(_SC_OPEN_MAX);
|
||||||
|
-#else /* USE_SYSCONF */
|
||||||
|
- cfg->conntablesize = getdtablesize();
|
||||||
|
-#endif /* USE_SYSCONF */
|
||||||
|
-
|
||||||
|
init_accesscontrol = cfg->accesscontrol = LDAP_ON;
|
||||||
|
|
||||||
|
/* nagle triggers set/unset TCP_CORK setsockopt per operation
|
||||||
|
@@ -1689,7 +1682,6 @@ FrontendConfig_init(void)
|
||||||
|
init_return_exact_case = cfg->return_exact_case = LDAP_ON;
|
||||||
|
init_result_tweak = cfg->result_tweak = LDAP_OFF;
|
||||||
|
init_attrname_exceptions = cfg->attrname_exceptions = LDAP_OFF;
|
||||||
|
- cfg->reservedescriptors = SLAPD_DEFAULT_RESERVE_FDS;
|
||||||
|
cfg->useroc = slapi_ch_strdup("");
|
||||||
|
cfg->userat = slapi_ch_strdup("");
|
||||||
|
/* kexcoff: should not be initialized by default here
|
||||||
|
@@ -4830,43 +4822,13 @@ config_set_maxdescriptors(const char *attrname, char *value, char *errorbuf, int
|
||||||
|
int
|
||||||
|
config_set_conntablesize(const char *attrname, char *value, char *errorbuf, int apply)
|
||||||
|
{
|
||||||
|
- int retVal = LDAP_SUCCESS;
|
||||||
|
- long nValue = 0;
|
||||||
|
- int maxVal = 65535;
|
||||||
|
- char *endp = NULL;
|
||||||
|
- struct rlimit rlp;
|
||||||
|
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
|
||||||
|
|
||||||
|
- if (config_value_is_null(attrname, value, errorbuf, 0)) {
|
||||||
|
- return LDAP_OPERATIONS_ERROR;
|
||||||
|
- }
|
||||||
|
+ slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
|
||||||
|
+ "User setting of %s attribute is disabled, server has auto calculated its value to %d.",
|
||||||
|
+ attrname, slapdFrontendConfig->conntablesize);
|
||||||
|
|
||||||
|
- if (0 == getrlimit(RLIMIT_NOFILE, &rlp)) {
|
||||||
|
- maxVal = (int)rlp.rlim_max;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- errno = 0;
|
||||||
|
- nValue = strtol(value, &endp, 0);
|
||||||
|
-
|
||||||
|
- if (*endp != '\0' || errno == ERANGE || nValue < 1 || nValue > maxVal) {
|
||||||
|
- slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
|
||||||
|
- "%s: invalid value \"%s\", connection table size must range from 1 to %d (the current process maxdescriptors limit). "
|
||||||
|
- "Server will use a setting of %d.",
|
||||||
|
- attrname, value, maxVal, maxVal);
|
||||||
|
- if (nValue > maxVal) {
|
||||||
|
- nValue = maxVal;
|
||||||
|
- retVal = LDAP_UNWILLING_TO_PERFORM;
|
||||||
|
- } else {
|
||||||
|
- retVal = LDAP_OPERATIONS_ERROR;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (apply) {
|
||||||
|
- CFG_LOCK_WRITE(slapdFrontendConfig);
|
||||||
|
- slapdFrontendConfig->conntablesize = nValue;
|
||||||
|
- CFG_UNLOCK_WRITE(slapdFrontendConfig);
|
||||||
|
- }
|
||||||
|
- return retVal;
|
||||||
|
+ return LDAP_OPERATIONS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
@@ -6293,6 +6255,19 @@ config_get_maxdescriptors(void)
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int
|
||||||
|
+config_get_conntablesize(void)
|
||||||
|
+{
|
||||||
|
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
|
||||||
|
+ int retVal;
|
||||||
|
+
|
||||||
|
+ CFG_LOCK_READ(slapdFrontendConfig);
|
||||||
|
+ retVal = slapdFrontendConfig->conntablesize;
|
||||||
|
+ CFG_UNLOCK_READ(slapdFrontendConfig);
|
||||||
|
+
|
||||||
|
+ return retVal;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int
|
||||||
|
config_get_reservedescriptors()
|
||||||
|
{
|
||||||
|
@@ -6595,19 +6570,6 @@ config_get_referral_mode(void)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int
|
||||||
|
-config_get_conntablesize(void)
|
||||||
|
-{
|
||||||
|
- slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
|
||||||
|
- int retVal;
|
||||||
|
-
|
||||||
|
- CFG_LOCK_READ(slapdFrontendConfig);
|
||||||
|
- retVal = slapdFrontendConfig->conntablesize;
|
||||||
|
- CFG_UNLOCK_READ(slapdFrontendConfig);
|
||||||
|
-
|
||||||
|
- return retVal;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
/* return yes/no without actually copying the referral url
|
||||||
|
we don't worry about another thread changing this value
|
||||||
|
since we now return an integer */
|
||||||
|
@@ -9135,3 +9097,188 @@ invalid_sasl_mech(char *str)
|
||||||
|
/* Mechanism value is valid */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Check if the number of reserve descriptors satisfy the servers needs.
|
||||||
|
+ *
|
||||||
|
+ * 1) Calculate the number of reserve descriptors the server requires
|
||||||
|
+ * 2) Get the configured value for nsslapd-reservedescriptors
|
||||||
|
+ * 3) If the configured value is less than the calculated value, increase it
|
||||||
|
+ *
|
||||||
|
+ * The formula used here is taken from the RH DS 11 docs:
|
||||||
|
+ * nsslapd-reservedescriptor = 20 + (NldbmBackends * 4) + NglobalIndex +
|
||||||
|
+ * 8 ReplicationDescriptors + Nreplicas +
|
||||||
|
+ * NchainingBackends * nsOperationCOnnectionsLImit +
|
||||||
|
+ * 3 PTADescriptors + 5 SSLDescriptors
|
||||||
|
+ */
|
||||||
|
+int
|
||||||
|
+validate_num_config_reservedescriptors(void)
|
||||||
|
+{
|
||||||
|
+ #define RESRV_DESC_CONST 20
|
||||||
|
+ #define BE_DESC_CONST 4
|
||||||
|
+ #define REPL_DESC_CONST 8
|
||||||
|
+ #define PTA_DESC_CONST 3
|
||||||
|
+ #define SSL_DESC_CONST 5
|
||||||
|
+ Slapi_Attr *attr = NULL;
|
||||||
|
+ Slapi_Backend *be = NULL;
|
||||||
|
+ Slapi_DN sdn;
|
||||||
|
+ Slapi_Entry *entry = NULL;
|
||||||
|
+ Slapi_Entry **entries = NULL;
|
||||||
|
+ Slapi_PBlock *search_pb = NULL;
|
||||||
|
+ char *cookie = NULL;
|
||||||
|
+ char const *mt_str = NULL;
|
||||||
|
+ char *entry_str = NULL;
|
||||||
|
+ int rc = -1;
|
||||||
|
+ int num_backends = 0;
|
||||||
|
+ int num_repl_agmts = 0;
|
||||||
|
+ int num_chaining_backends = 0;
|
||||||
|
+ int chain_conn_limit = 0;
|
||||||
|
+ int calc_reservedesc = RESRV_DESC_CONST;
|
||||||
|
+ int config_reservedesc = config_get_reservedescriptors();
|
||||||
|
+
|
||||||
|
+ /* Get number of backends, multiplied by the backend descriptor constant */
|
||||||
|
+ for (be = slapi_get_first_backend(&cookie); be != NULL; be = slapi_get_next_backend(cookie)) {
|
||||||
|
+ entry_str = slapi_create_dn_string("cn=%s,cn=ldbm database,cn=plugins,cn=config", be->be_name);
|
||||||
|
+ if (NULL == entry_str) {
|
||||||
|
+ slapi_log_err(SLAPI_LOG_ERR, "validate_num_config_reservedescriptors", "Failed to create backend dn string");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ slapi_sdn_init_dn_byref(&sdn, entry_str);
|
||||||
|
+ slapi_search_internal_get_entry(&sdn, NULL, &entry, plugin_get_default_component_id());
|
||||||
|
+ if (entry) {
|
||||||
|
+ if (slapi_entry_attr_hasvalue(entry, "objectclass", "nsBackendInstance")) {
|
||||||
|
+ num_backends += 1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ slapi_entry_free(entry);
|
||||||
|
+ slapi_ch_free_string(&entry_str);
|
||||||
|
+ slapi_sdn_done(&sdn);
|
||||||
|
+ }
|
||||||
|
+ slapi_ch_free((void **)&cookie);
|
||||||
|
+ if (num_backends) {
|
||||||
|
+ calc_reservedesc += (num_backends * BE_DESC_CONST);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Get number of indexes for each backend and add to total */
|
||||||
|
+ for (be = slapi_get_first_backend(&cookie); be; be = slapi_get_next_backend(cookie)) {
|
||||||
|
+ entry_str = slapi_create_dn_string("cn=index,cn=%s,cn=ldbm database,cn=plugins,cn=config", be->be_name);
|
||||||
|
+ if (NULL == entry_str) {
|
||||||
|
+ slapi_log_err(SLAPI_LOG_ERR, "validate_num_config_reservedescriptors", "Failed to create index dn string");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ slapi_sdn_init_dn_byref(&sdn, entry_str);
|
||||||
|
+ slapi_search_internal_get_entry(&sdn, NULL, &entry, plugin_get_default_component_id());
|
||||||
|
+ if (entry) {
|
||||||
|
+ rc = slapi_entry_attr_find(entry, "numsubordinates", &attr);
|
||||||
|
+ if (LDAP_SUCCESS == rc) {
|
||||||
|
+ Slapi_Value *sval;
|
||||||
|
+ slapi_attr_first_value(attr, &sval);
|
||||||
|
+ if (sval != NULL) {
|
||||||
|
+ const struct berval *bval = slapi_value_get_berval(sval);
|
||||||
|
+ if (NULL != bval)
|
||||||
|
+ calc_reservedesc += atol(bval->bv_val);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ slapi_entry_free(entry);
|
||||||
|
+ slapi_ch_free_string(&entry_str);
|
||||||
|
+ slapi_sdn_done(&sdn);
|
||||||
|
+ }
|
||||||
|
+ slapi_ch_free((void **)&cookie);
|
||||||
|
+
|
||||||
|
+ /* If replication is enabled add replication descriptor constant, plus the number of enabled repl agmts */
|
||||||
|
+ mt_str = slapi_get_mapping_tree_config_root();
|
||||||
|
+ if (NULL == mt_str) {
|
||||||
|
+ slapi_log_err(SLAPI_LOG_ERR, "validate_num_config_reservedescriptors", "Failed to get mapping tree config string");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ search_pb = slapi_pblock_new();
|
||||||
|
+ slapi_search_internal_set_pb(search_pb, mt_str, LDAP_SCOPE_SUBTREE, "(objectClass=nsds5replicationagreement) nsds5ReplicaEnabled", NULL, 0, NULL, NULL, plugin_get_default_component_id(), 0);
|
||||||
|
+ slapi_search_internal_pb(search_pb);
|
||||||
|
+ slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
|
||||||
|
+ if (LDAP_SUCCESS == rc) {
|
||||||
|
+ slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
|
||||||
|
+ for (; *entries; ++entries) {
|
||||||
|
+ num_repl_agmts += 1;
|
||||||
|
+ }
|
||||||
|
+ if (num_repl_agmts) {
|
||||||
|
+ calc_reservedesc += REPL_DESC_CONST;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ slapi_free_search_results_internal(search_pb);
|
||||||
|
+ slapi_pblock_destroy(search_pb);
|
||||||
|
+ calc_reservedesc += num_repl_agmts;
|
||||||
|
+
|
||||||
|
+ /* Get the operation connection limit from the default instance config */
|
||||||
|
+ entry_str = slapi_create_dn_string("cn=default instance config,cn=chaining database,cn=plugins,cn=config");
|
||||||
|
+ if (NULL == entry_str) {
|
||||||
|
+ slapi_log_err(SLAPI_LOG_ERR, "validate_num_config_reservedescriptors", "Failed to create default chaining config dn string");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ slapi_sdn_init_dn_byref(&sdn, entry_str);
|
||||||
|
+ slapi_search_internal_get_entry(&sdn, NULL, &entry, plugin_get_default_component_id());
|
||||||
|
+ if (entry) {
|
||||||
|
+ chain_conn_limit = slapi_entry_attr_get_int(entry, "nsoperationconnectionslimit");
|
||||||
|
+ }
|
||||||
|
+ slapi_entry_free(entry);
|
||||||
|
+ slapi_ch_free_string(&entry_str);
|
||||||
|
+ slapi_sdn_done(&sdn);
|
||||||
|
+
|
||||||
|
+ /* Get the number of chaining backends, multiplied by the chaining operation connection limit */
|
||||||
|
+ for (be = slapi_get_first_backend(&cookie); be; be = slapi_get_next_backend(cookie)) {
|
||||||
|
+ entry_str = slapi_create_dn_string("cn=%s,cn=chaining database,cn=plugins,cn=config", be->be_name);
|
||||||
|
+ if (NULL == entry_str) {
|
||||||
|
+ slapi_log_err(SLAPI_LOG_ERR, "validate_num_config_reservedescriptors", "Failed to create chaining be dn string");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ slapi_sdn_init_dn_byref(&sdn, entry_str);
|
||||||
|
+ slapi_search_internal_get_entry(&sdn, NULL, &entry, plugin_get_default_component_id());
|
||||||
|
+ if (entry) {
|
||||||
|
+ if (slapi_entry_attr_hasvalue(entry, "objectclass", "nsBackendInstance")) {
|
||||||
|
+ num_chaining_backends += 1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ slapi_entry_free(entry);
|
||||||
|
+ slapi_ch_free_string(&entry_str);
|
||||||
|
+ slapi_sdn_done(&sdn);
|
||||||
|
+ }
|
||||||
|
+ slapi_ch_free((void **)&cookie);
|
||||||
|
+ if (num_chaining_backends) {
|
||||||
|
+ calc_reservedesc += (num_chaining_backends * chain_conn_limit);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* If PTA is enabled add the pass through auth descriptor constant */
|
||||||
|
+ entry_str = slapi_create_dn_string("cn=Pass Through Authentication,cn=plugins,cn=config");
|
||||||
|
+ if (NULL == entry_str) {
|
||||||
|
+ slapi_log_err(SLAPI_LOG_ERR, "validate_num_config_reservedescriptors", "Failed to create PTA dn string");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ slapi_sdn_init_dn_byref(&sdn, entry_str);
|
||||||
|
+ slapi_search_internal_get_entry(&sdn, NULL, &entry, plugin_get_default_component_id());
|
||||||
|
+ if (entry) {
|
||||||
|
+ if (slapi_entry_attr_hasvalue(entry, "nsslapd-PluginEnabled", "on")) {
|
||||||
|
+ calc_reservedesc += PTA_DESC_CONST;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ slapi_entry_free(entry);
|
||||||
|
+ slapi_ch_free_string(&entry_str);
|
||||||
|
+ slapi_sdn_done(&sdn);
|
||||||
|
+
|
||||||
|
+ /* If SSL is enabled add the SSL descriptor constant */;;
|
||||||
|
+ if (config_get_security()) {
|
||||||
|
+ calc_reservedesc += SSL_DESC_CONST;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ char errorbuf[SLAPI_DSE_RETURNTEXT_SIZE];
|
||||||
|
+ char resrvdesc_str[SLAPI_DSE_RETURNTEXT_SIZE];
|
||||||
|
+ /* Are the configured reserve descriptors enough to satisfy the servers needs */
|
||||||
|
+ if (config_reservedesc < calc_reservedesc) {
|
||||||
|
+ PR_snprintf(resrvdesc_str, sizeof(resrvdesc_str), "%d", calc_reservedesc);
|
||||||
|
+ if (LDAP_SUCCESS == config_set_reservedescriptors(CONFIG_RESERVEDESCRIPTORS_ATTRIBUTE, resrvdesc_str, errorbuf, 1)) {
|
||||||
|
+ slapi_log_err(SLAPI_LOG_INFO, "validate_num_config_reservedescriptors",
|
||||||
|
+ "reserve descriptors changed from %d to %d\n", config_reservedesc, calc_reservedesc);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return (0);
|
||||||
|
+}
|
||||||
|
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
|
||||||
|
index 65efee8542..47465c4c5c 100644
|
||||||
|
--- a/ldap/servers/slapd/proto-slap.h
|
||||||
|
+++ b/ldap/servers/slapd/proto-slap.h
|
||||||
|
@@ -349,7 +349,7 @@ int config_set_useroc(const char *attrname, char *value, char *errorbuf, int app
|
||||||
|
int config_set_return_exact_case(const char *attrname, char *value, char *errorbuf, int apply);
|
||||||
|
int config_set_result_tweak(const char *attrname, char *value, char *errorbuf, int apply);
|
||||||
|
int config_set_referral_mode(const char *attrname, char *url, char *errorbuf, int apply);
|
||||||
|
-int config_set_conntablesize(const char *attrname, char *url, char *errorbuf, int apply);
|
||||||
|
+int config_set_conntablesize(const char *attrname, char *value, char *errorbuf, int apply);
|
||||||
|
int config_set_maxbersize(const char *attrname, char *value, char *errorbuf, int apply);
|
||||||
|
int config_set_maxsasliosize(const char *attrname, char *value, char *errorbuf, int apply);
|
||||||
|
int config_set_versionstring(const char *attrname, char *versionstring, char *errorbuf, int apply);
|
||||||
|
@@ -645,6 +645,10 @@ int get_ldapmessage_controls_ext(Slapi_PBlock *pb, BerElement *ber, LDAPControl
|
||||||
|
int write_controls(BerElement *ber, LDAPControl **ctrls);
|
||||||
|
void add_control(LDAPControl ***ctrlsp, LDAPControl *newctrl);
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * daemon.c
|
||||||
|
+ */
|
||||||
|
+int validate_num_config_reservedescriptors(void) ;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* delete.c
|
@ -0,0 +1,71 @@
|
|||||||
|
From dc4130da52cae8aea54c0a664429550344ec94b4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mark Reynolds <mreynolds@redhat.com>
|
||||||
|
Date: Wed, 5 Jul 2023 13:52:50 -0400
|
||||||
|
Subject: [PATCH] Issue 5825 - healthcheck - password storage scheme warning
|
||||||
|
needs more info
|
||||||
|
|
||||||
|
Description: Add the current/insecure scheme to the report, and state which
|
||||||
|
config setting is insecure.
|
||||||
|
|
||||||
|
relates: https://github.com/389ds/389-ds-base/issues/5825
|
||||||
|
|
||||||
|
Reviewed by: jchapman & spichugi(Thanks!!)
|
||||||
|
---
|
||||||
|
src/lib389/lib389/config.py | 13 ++++++++++++-
|
||||||
|
src/lib389/lib389/lint.py | 10 +++-------
|
||||||
|
2 files changed, 15 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/lib389/lib389/config.py b/src/lib389/lib389/config.py
|
||||||
|
index b1a474ebed..81bf8ec667 100644
|
||||||
|
--- a/src/lib389/lib389/config.py
|
||||||
|
+++ b/src/lib389/lib389/config.py
|
||||||
|
@@ -214,9 +214,20 @@ def _lint_passwordscheme(self):
|
||||||
|
allowed_schemes = ['PBKDF2-SHA512', 'PBKDF2_SHA256', 'PBKDF2_SHA512', 'GOST_YESCRYPT']
|
||||||
|
u_password_scheme = self.get_attr_val_utf8('passwordStorageScheme')
|
||||||
|
u_root_scheme = self.get_attr_val_utf8('nsslapd-rootpwstoragescheme')
|
||||||
|
- if u_root_scheme not in allowed_schemes or u_password_scheme not in allowed_schemes:
|
||||||
|
+ if u_root_scheme not in allowed_schemes:
|
||||||
|
report = copy.deepcopy(DSCLE0002)
|
||||||
|
+ report['detail'] = report['detail'].replace('SCHEME', u_root_scheme)
|
||||||
|
+ report['detail'] = report['detail'].replace('CONFIG', 'nsslapd-rootpwstoragescheme')
|
||||||
|
report['fix'] = report['fix'].replace('YOUR_INSTANCE', self._instance.serverid)
|
||||||
|
+ report['fix'] = report['fix'].replace('CONFIG', 'nsslapd-rootpwstoragescheme')
|
||||||
|
+ report['check'] = "config:passwordscheme"
|
||||||
|
+ yield report
|
||||||
|
+ if u_password_scheme not in allowed_schemes:
|
||||||
|
+ report = copy.deepcopy(DSCLE0002)
|
||||||
|
+ report['detail'] = report['detail'].replace('SCHEME', u_password_scheme)
|
||||||
|
+ report['detail'] = report['detail'].replace('CONFIG', 'passwordStorageScheme')
|
||||||
|
+ report['fix'] = report['fix'].replace('YOUR_INSTANCE', self._instance.serverid)
|
||||||
|
+ report['fix'] = report['fix'].replace('CONFIG', 'passwordStorageScheme')
|
||||||
|
report['check'] = "config:passwordscheme"
|
||||||
|
yield report
|
||||||
|
|
||||||
|
diff --git a/src/lib389/lib389/lint.py b/src/lib389/lib389/lint.py
|
||||||
|
index 7ca524315d..475ab08bd2 100644
|
||||||
|
--- a/src/lib389/lib389/lint.py
|
||||||
|
+++ b/src/lib389/lib389/lint.py
|
||||||
|
@@ -97,20 +97,16 @@
|
||||||
|
In Directory Server, we offer one hash suitable for this (PBKDF2-SHA512) and one hash
|
||||||
|
for "legacy" support (SSHA512).
|
||||||
|
|
||||||
|
-Your configuration does not use these for password storage or the root password storage
|
||||||
|
-scheme.
|
||||||
|
+Your configured scheme (SCHEME) for 'CONFIG' is not secure
|
||||||
|
""",
|
||||||
|
'fix': """Perform a configuration reset of the values:
|
||||||
|
|
||||||
|
-passwordStorageScheme
|
||||||
|
-nsslapd-rootpwstoragescheme
|
||||||
|
-
|
||||||
|
-IE, stop Directory Server, and in dse.ldif delete these two lines. When Directory Server
|
||||||
|
+IE, stop Directory Server, and in dse.ldif delete this line (CONFIG). When Directory Server
|
||||||
|
is started, they will use the server provided defaults that are secure.
|
||||||
|
|
||||||
|
You can also use 'dsconf' to replace these values. Here is an example:
|
||||||
|
|
||||||
|
- # dsconf slapd-YOUR_INSTANCE config replace passwordStorageScheme=PBKDF2-SHA512 nsslapd-rootpwstoragescheme=PBKDF2-SHA512"""
|
||||||
|
+ # dsconf slapd-YOUR_INSTANCE config replace CONFIG=PBKDF2-SHA512"""
|
||||||
|
}
|
||||||
|
|
||||||
|
DSCLE0003 = {
|
@ -0,0 +1,43 @@
|
|||||||
|
From b6d160d5a944dbab440d484fedbdcfcc3b85fff9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Viktor Ashirov <vashirov@redhat.com>
|
||||||
|
Date: Wed, 26 Jul 2023 16:44:51 +0200
|
||||||
|
Subject: [PATCH] Issue 5864 - Server fails to start after reboot because it's
|
||||||
|
unable to access nsslapd-rundir
|
||||||
|
|
||||||
|
Bug Description:
|
||||||
|
Sometimes after reboot dirsrv service fails to start:
|
||||||
|
|
||||||
|
EMERG - main - Unable to access nsslapd-rundir: No such file or directory
|
||||||
|
EMERG - main - Ensure that user "dirsrv" has read and write permissions on /run/dirsrv
|
||||||
|
EMERG - main - Shutting down.
|
||||||
|
|
||||||
|
We rely on systemd-tmpfiles for /run/dirsrv creation. But dirsrv service
|
||||||
|
doesn't explicitly wait for systemd-tmpfiles-setup.service to start.
|
||||||
|
This creates a race condition.
|
||||||
|
|
||||||
|
Fix Description:
|
||||||
|
dirsrv service should start only after systemd-tmpfiles-setup.service is finished,
|
||||||
|
add it as a dependency via `After=` and `Wants=`.
|
||||||
|
|
||||||
|
Fixes: https://github.com/389ds/389-ds-base/issues/5864
|
||||||
|
|
||||||
|
Reviwed-by: @Firstyear (Thanks!)
|
||||||
|
---
|
||||||
|
wrappers/systemd.template.service.in | 3 ++-
|
||||||
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/wrappers/systemd.template.service.in b/wrappers/systemd.template.service.in
|
||||||
|
index 4485e0ec0a..4a44eb0e43 100644
|
||||||
|
--- a/wrappers/systemd.template.service.in
|
||||||
|
+++ b/wrappers/systemd.template.service.in
|
||||||
|
@@ -4,8 +4,9 @@
|
||||||
|
[Unit]
|
||||||
|
Description=@capbrand@ Directory Server %i.
|
||||||
|
PartOf=@systemdgroupname@
|
||||||
|
-After=chronyd.service ntpd.service network-online.target
|
||||||
|
+After=chronyd.service ntpd.service network-online.target systemd-tmpfiles-setup.service
|
||||||
|
Before=radiusd.service
|
||||||
|
+Wants=systemd-tmpfiles-setup.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=notify
|
@ -0,0 +1,34 @@
|
|||||||
|
From ccff99df6741e7e6bdc9f9aba3a05f9288efdd3b Mon Sep 17 00:00:00 2001
|
||||||
|
From: progier389 <progier@redhat.com>
|
||||||
|
Date: Mon, 7 Aug 2023 10:18:19 +0200
|
||||||
|
Subject: [PATCH] Issue 5883 - Remove connection mutex contention risk on
|
||||||
|
autobind (#5886)
|
||||||
|
|
||||||
|
Problem: A contention on the connection c_mutex is blocking the listener thread when autobind is performed.
|
||||||
|
Solution: Let the listener thread skip the connection if the mutex is held by another thread
|
||||||
|
Reviewed by: @mreynolds389 , @droideck Thanks
|
||||||
|
|
||||||
|
(cherry picked from commit 599db0a450357e804072ca03421c9f65351cdf1f)
|
||||||
|
---
|
||||||
|
ldap/servers/slapd/daemon.c | 8 +++++++-
|
||||||
|
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
|
||||||
|
index e5b7d6e06a..e44d0c9b5b 100644
|
||||||
|
--- a/ldap/servers/slapd/daemon.c
|
||||||
|
+++ b/ldap/servers/slapd/daemon.c
|
||||||
|
@@ -1675,7 +1675,13 @@ handle_pr_read_ready(Connection_Table *ct, PRIntn num_poll __attribute__((unused
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
- pthread_mutex_lock(&(c->c_mutex));
|
||||||
|
+ /* Try to get connection mutex, if not available just skip the connection and
|
||||||
|
+ * process other connections events. May generates cpu load for listening thread
|
||||||
|
+ * if connection mutex is held for a long time
|
||||||
|
+ */
|
||||||
|
+ if (pthread_mutex_trylock(&(c->c_mutex)) == EBUSY) {
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
if (connection_is_active_nolock(c) && c->c_gettingber == 0) {
|
||||||
|
PRInt16 out_flags;
|
||||||
|
short readready;
|
@ -48,7 +48,7 @@ ExcludeArch: i686
|
|||||||
Summary: 389 Directory Server (base)
|
Summary: 389 Directory Server (base)
|
||||||
Name: 389-ds-base
|
Name: 389-ds-base
|
||||||
Version: 1.4.3.35
|
Version: 1.4.3.35
|
||||||
Release: %{?relprefix}1%{?prerel}%{?dist}
|
Release: %{?relprefix}2%{?prerel}%{?dist}.alma.1
|
||||||
License: GPLv3+ and ASL 2.0 and MIT
|
License: GPLv3+ and ASL 2.0 and MIT
|
||||||
URL: https://www.port389.org
|
URL: https://www.port389.org
|
||||||
Group: System Environment/Daemons
|
Group: System Environment/Daemons
|
||||||
@ -297,6 +297,24 @@ Source4: vendor-%{version}-1.tar.gz
|
|||||||
Source5: Cargo-%{version}.lock
|
Source5: Cargo-%{version}.lock
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
|
# Patches were taken from upstream git:
|
||||||
|
# https://github.com/389ds/389-ds-base/issues/5789
|
||||||
|
Patch001: Issue-5789-Improve-ds-replcheck-error-handling.patch
|
||||||
|
# https://github.com/389ds/389-ds-base/issues/5646
|
||||||
|
Patch002: Issue-5646-Various-memory-leaks-5725.patch
|
||||||
|
# https://github.com/389ds/389-ds-base/issues/2375
|
||||||
|
Patch003: Issue-2375-CLI-Healthcheck-revise-and-add-new-checks.patch
|
||||||
|
# https://github.com/389ds/389-ds-base/issues/4551
|
||||||
|
Patch004: Issue-4551-Paged-search-impacts-performance-5838.patch
|
||||||
|
# https://github.com/389ds/389-ds-base/issues/5804
|
||||||
|
Patch005: Issue-5804-dtablesize-being-set-to-soft-maxfiledescr.patch
|
||||||
|
# https://github.com/389ds/389-ds-base/issues/5825
|
||||||
|
Patch006: Issue-5825-healthcheck-password-storage-scheme-warni.patch
|
||||||
|
# https://github.com/389ds/389-ds-base/issues/5864
|
||||||
|
Patch007: Issue-5864-Server-fails-to-start-after-reboot-becaus.patch
|
||||||
|
# https://github.com/389ds/389-ds-base/issues/5883
|
||||||
|
Patch008: Issue-5883-Remove-connection-mutex-contention-risk-o.patch
|
||||||
|
|
||||||
%description
|
%description
|
||||||
389 Directory Server is an LDAPv3 compliant server. The base package includes
|
389 Directory Server is an LDAPv3 compliant server. The base package includes
|
||||||
the LDAP server and command line utilities for server administration.
|
the LDAP server and command line utilities for server administration.
|
||||||
@ -917,6 +935,16 @@ exit 0
|
|||||||
%doc README.md
|
%doc README.md
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Sep 21 2023 Eduard Abdullin <eabdullin@almalinux.org> - 1.4.3.35-2.alma.1
|
||||||
|
- Fix Issue-5789-Improve-ds-replcheck-error-handling.patch
|
||||||
|
- Fix Issue-5646-Various-memory-leaks-5725.patch
|
||||||
|
- Fix Issue-2375-CLI-Healthcheck-revise-and-add-new-checks.patch
|
||||||
|
- Fix Issue-4551-Paged-search-impacts-performance-5838.patch
|
||||||
|
- Fix Issue-5804-dtablesize-being-set-to-soft-maxfiledescr.patch
|
||||||
|
- Fix Issue-5825-healthcheck-password-storage-scheme-warni.patch
|
||||||
|
- Fix Issue-5864-Server-fails-to-start-after-reboot-becaus.patch
|
||||||
|
- Fix Issue-5883-Remove-connection-mutex-contention-risk-o.patch
|
||||||
|
|
||||||
* Mon May 22 2023 Mark Reynolds <mreynolds@redhat.com> - 1.4.3.35-1
|
* Mon May 22 2023 Mark Reynolds <mreynolds@redhat.com> - 1.4.3.35-1
|
||||||
- Bump version to 1.4.3.35-1
|
- Bump version to 1.4.3.35-1
|
||||||
- Resolves: rhbz#2188628 - Rebase 389-ds-base in RHEL 8.9 to 1.4.3.25
|
- Resolves: rhbz#2188628 - Rebase 389-ds-base in RHEL 8.9 to 1.4.3.25
|
||||||
|
Loading…
Reference in New Issue
Block a user