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:

Bruce Adams
  • 612
  • 1
  • 9
  • 21
  • 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
  • 411,918
  • 54
  • 1,065
  • 1,164