0

After installing the an RPM on centos8 I found that the package manager dnf - inexplicably stopped working with a cryptic error:

Traceback (most recent call last):
File "/usr/lib64/python3.6/site-packages/libdnf/common_types.py", line 14, in swig_import_helper
return importlib.import_module(mname)
File "/usr/lib64/python3.6/importlib/init.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 994, in _gcd_import
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 658, in _load_unlocked
File "<frozen importlib._bootstrap>", line 571, in module_from_spec
File "<frozen importlib._bootstrap_external>", line 922, in create_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
ImportError: /lib64/libdnf.so.2: undefined symbol: sqlite3_expanded_sql

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "/usr/bin/dnf", line 57, in <module> from dnf.cli import main File "/usr/lib/python3.6/site-packages/dnf/init.py", line 30, in <module> import dnf.base File "/usr/lib/python3.6/site-packages/dnf/base.py", line 29, in <module> import libdnf.transaction File "/usr/lib64/python3.6/site-packages/libdnf/init.py", line 3, in <module> from . import common_types File "/usr/lib64/python3.6/site-packages/libdnf/common_types.py", line 17, in <module> _common_types = swig_import_helper() File "/usr/lib64/python3.6/site-packages/libdnf/common_types.py", line 16, in swig_import_helper return importlib.import_module('_common_types') File "/usr/lib64/python3.6/importlib/init.py", line 126, in import_module return _bootstrap._gcd_import(name[level:], package, level) ModuleNotFoundError: No module named '_common_types'

After a lot of head scratching I discovered the problem was because the RPM installed its own copy of libsqlite3.so to a path in /opt//lib and in the post install script added a entry for /opt//lib to ld.so.conf . For some reason dnf picks up this version rather than the system version in /usr/lib64 which it normally uses.

So the question I have is why is /usr/lib64 not earlier on the search path than entries in ld.so.conf I cannot find where /usr/lib64 is configured. Is it hard-coded into LD or the kernel?

Note that /usr/lib64/libdnf.so.2 is already in /usr/lib64 so why isn't /usr/lib64 searched first?

My fix was to add an entry for /usr/lib64 to ld.so.conf. Is this the best approach? I think perhaps it would be better for /opt/ to be using RPATH to find the libraries and not adding anything to ld.so.conf at all.

How does this fit in to:

  • What version of Python are you using? Add the output of echo $PATH to your question. – Nasir Riley Aug 27 '20 at 11:12
  • @Nasir the version of Python is given in the error, 3.6. The significant part of the error is ImportError: /lib64/libdnf.so.2: undefined symbol: sqlite3_expanded_sql and its cause is already explained in the question. This has nothing to do with PATH, the error shows that /usr/bin/dnf is the command being used. – Stephen Kitt Aug 27 '20 at 11:55
  • @StephenKitt I know that dnf is the command being used. I simply wanted to see if he had a different version of Python (or one of its variants) in his PATH that was conflicting. That can cause issues with dnf and yum because they both depend on Python. This often happens when prepending wxpython to root's PATH. – Nasir Riley Aug 27 '20 at 12:33
  • A custom version of Python would be unlikely to use /usr/lib64/python3.6/site-packages... – Stephen Kitt Aug 27 '20 at 12:40
  • @StephenKitt That's true. It would be better to ask him to add the output of echo $LD_LIBRARY_PATH. He could very well have something different in both but that's the most likely. – Nasir Riley Aug 27 '20 at 12:52

1 Answers1

1

why is /usr/lib64 not earlier on the search path than entries in ld.so.conf

In the absence of any other configuration, the system library paths are the last entries on the search path.

I cannot find where /usr/lib64 is configured. Is it hard-coded into LD or the kernel?

It’s hard-coded in ld.so, the dynamic linker (/lib64/ld-linux-x86-64.so.2 in your case, assuming you’re on x86_64). See What is the default value of LD_LIBRARY_PATH? for details.

Your fix is probably the best you can do without touching the package’s contents. As you say, a better fix would be to set the package’s binaries’ rpath, or to add wrapper shell scripts to set LD_LIBRARY_PATH when invoking the binaries.

Stephen Kitt
  • 434,908