diff --git a/dirsrvtests/tests/suites/clu/dsctl_dblib_test.py b/dirsrvtests/tests/suites/clu/dsctl_dblib_test.py index a20536fe6..141384bb4 100644 --- a/dirsrvtests/tests/suites/clu/dsctl_dblib_test.py +++ b/dirsrvtests/tests/suites/clu/dsctl_dblib_test.py @@ -17,7 +17,7 @@ from lib389.idm.user import UserAccounts from lib389.replica import ReplicationManager from lib389.topologies import topology_m2 as topo_m2, topology_st as topo_st -from lib389.utils import check_installed_packages, check_plugin_symbols +from lib389.utils import check_plugin_strings log = logging.getLogger(__name__) @@ -137,14 +137,14 @@ def test_dblib_migration(init_user): repl.test_replication_topology([s1, s2]) -def test_check_installed_packages(): +def test_check_plugin_strings(): """ - Check that lib389.utils check_installed_packages is working properly + Check that lib389.utils check_plugin_strings is working properly :id: 5194e88a-80c6-11ef-a2ee-482ae39447e5 :setup: None :steps: - 1. Call check_installed_packages + 1. Call check_plugin_strings 2. Check that an installed rpm is detected 3. Check that a non installed rpm is not detected :expectedresults: @@ -152,29 +152,7 @@ def test_check_installed_packages(): 2. Success 3. Success """ - res = check_installed_packages(('389-ds-base', 'Dummyrpm')) - log.info(f'check_installed_packages returned {res}') - assert res['389-ds-base'] is True - assert res['Dummyrpm'] is False - - -def test_check_plugin_symbols(): - """ - Check that lib389.utils check_installed_packages is working properly - - :id: 1cb19ebe-80c7-11ef-9516-482ae39447e5 - :setup: None - :steps: - 1. Call check_plugin_symbols - 2. Check that an existing symbol is found - 3. Check that a not existing symbol is not found - :expectedresults: - 1. Success - 2. Success - 3. Success - """ - res = check_plugin_symbols('libback-ldbm', ('ldbm_back_search', 'DummySymbol')) - log.info(f'check_plugin_symbols returned {res}') + res = check_plugin_strings('libback-ldbm', ('ldbm_back_search', 'DummyString')) + log.info(f'check_plugin_strings returned {res}') assert res['ldbm_back_search'] is True - assert res['DummySymbol'] is False - + assert res['DummyString'] is False diff --git a/src/lib389/lib389/cli_ctl/dblib.py b/src/lib389/lib389/cli_ctl/dblib.py index f24c42ccc..d47db4dcd 100644 --- a/src/lib389/lib389/cli_ctl/dblib.py +++ b/src/lib389/lib389/cli_ctl/dblib.py @@ -22,7 +22,7 @@ from lib389.cli_base import CustomHelpFormatter from lib389._constants import DEFAULT_LMDB_SIZE, BDB_IMPL_STATUS, DN_CONFIG from lib389.dseldif import DSEldif -from lib389.utils import parse_size, format_size +from lib389.utils import parse_size, format_size, check_plugin_strings, find_plugin_path from pathlib import Path @@ -35,14 +35,6 @@ MDB_LOCK = "lock.mdb" LDBM_DN = "cn=config,cn=ldbm database,cn=plugins,cn=config" -BDB_BUNDLED_RPM = '389-ds-base-bdb' -BDB_RPM = 'libdb' -TESTED_PACKAGES = ( BDB_BUNDLED_RPM, BDB_RPM ) -BDBRO_SYMBOL = 'bdbro_getcb_vector' -BDB_SYMBOL = 'bdb_start' -TESTED_SYMBOLS = ( BDB_SYMBOL, BDBRO_SYMBOL ) - - CL5DB='replication_changelog.db' _log = None @@ -58,16 +50,23 @@ def __init__(self, *args, **kwargs): def get_bdb_impl_status(): - pkgs = check_installed_packages(TESTED_PACKAGES) - symbs = check_plugin_symbols('libback-ldbm', TESTED_SYMBOLS) - if pkgs[BDB_BUNDLED_RPM] is True: - return BDB_IMPL_STATUS.BUNDLED - if symbs[BDBRO_SYMBOL] is True: - return BDB_IMPL_STATUS.READ_ONLY - if pkgs[BDB_RPM] is not False and symbs[BDB_SYMBOL] is True: - return BDB_IMPL_STATUS.RPM - if symbs[BDB_SYMBOL] is False and pkgs[BDB_BUNDLED_RPM] is False: + backldbm = 'libback-ldbm' + bundledbdb_plugin = 'libback-bdb' + robdb_symbol = 'bdbro_getcb_vector' + libdb = 'libdb-' + plgstrs = check_plugin_strings(backldbm, [bundledbdb_plugin, robdb_symbol, libdb]) + if plgstrs[bundledbdb_plugin] is True: + # bundled bdb build + if find_plugin_path(bundledbdb_plugin): + return BDB_IMPL_STATUS.BUNDLED return BDB_IMPL_STATUS.NONE + if plgstrs[robdb_symbol] is True: + # read-only bdb build + return BDB_IMPL_STATUS.READ_ONLY + if plgstrs[libdb] is True: + # standard bdb package build + return BDB_IMPL_STATUS.STABDARD + # Unable to find libback-ldbm plugin return BDB_IMPL_STATUS.UNKNOWN diff --git a/src/lib389/lib389/utils.py b/src/lib389/lib389/utils.py index 86bd12159..660fb1f0e 100644 --- a/src/lib389/lib389/utils.py +++ b/src/lib389/lib389/utils.py @@ -31,6 +31,7 @@ def wait(self): import logging import shutil import ldap +import mmap import socket import time import stat @@ -189,6 +190,7 @@ def wait(self): SIZE_PATTERN = r'\s*(\d*\.?\d*)\s*([tgmk]?)b?\s*' RPM_TOOL = '/usr/bin/rpm' +LDD_TOOL = '/usr/bin/ldd' OBJDUMP_TOOL = '/usr/bin/objdump' # @@ -1763,7 +1765,7 @@ def get_default_mdb_max_size(paths): # otherwise decrease the value dbdir = paths.db_dir # dbdir may not exists because: - # - paths instance name has not been expanded + # - paths instance name has not been expanded # - dscreate has not yet created it. # so let use the first existing parent in that case. while not os.path.exists(dbdir): @@ -1990,38 +1992,24 @@ def get_passwd_from_file(passwd_file): raise ValueError(f"The password file '{passwd_file}' does not exist, or can not be read.") -def check_installed_packages(tested_packages): - """ - Returns a dict mapping each tested rpm package to True, False or None - """ - try: - from rpm import TransactionSet - ts = TransactionSet() - pkgs = { pkgname:(len ([ pkg for pkg in ts.dbMatch( 'name', \ - pkgname ) ]) > 0) for pkgname in tested_packages} - ts.closeDB() - return pkgs - except ImportError: - if os.path.isfile(RPM_TOOL): - pkgs = { pkgname:( subprocess.run([RPM_TOOL, '-q', pkgname], \ - stdin=subprocess.DEVNULL,stderr=subprocess.DEVNULL \ - ).returncode == 0 ) for pkgname in tested_packages } - else: - pkgs = { pkg:None for pkg in tested_packages} - return pkgs +def find_plugin_path(plugin_name): + p = Paths() + plugin = None + for ppath in glob.glob(f'{p.plugin_dir}/{plugin_name}.*'): + if not ppath.endswith('.la'): + plugin = ppath + return plugin -def check_plugin_symbols(plugin_name, tested_symbols): +def check_plugin_strings(plugin_name, tested_strings): """ Returns a dict mapping each tested symbol to True, False or None """ - p = Paths() - plugin = None - for ppath in glob.glob(f'{p.plugin_dir}/{plugin_name}.*'): - plugin = ppath - if plugin and os.path.isfile(OBJDUMP_TOOL): - rc = subprocess.run(['objdump', '-R', plugin], text=True, capture_output=True) - return { symb: symb in rc.stdout for symb in tested_symbols } - else: - return { symb: None for symb in tested_symbols } + plugin = find_plugin_path(plugin_name) + if plugin: + # Otherwise looks directly for the string in the plugin + with open(plugin, "rb") as f: + with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as mm: + return { astring:(mm.find(astring.encode()) >=0) for astring in tested_strings } + return { astring:None for astring in tested_strings }