近日笔者对一台装有 CentOS 7.9 系统的服务器反复折腾,玩到最后发现 yum 命令用不了,总是报下面的错误信息:
There was a problem importing one of the Python modules
required to run yum. The error leading to this problem was:
/usr/lib64/python2.7/site-packages/pycurl.so: undefined symbol: CRYPTO_num_locks
Please install a package which provides this module, or
verify that the module is installed correctly.
It's possible that the above module doesn't match the
current version of Python, which is:
2.7.5 (default, Nov 14 2023, 16:14:06)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
If you cannot solve this problem yourself, please go to
the yum faq at:
http://yum.baseurl.org/wiki/Faq
服务器原先装有 Python 2.7.5,因我安装了 Python 3.10,怀疑是版本冲突造成,尝试删除 Python 3.10 后仍然无济于事,这下 yum 被我玩坏了。yum 命令是基于 Python 2.7.5版的,尽管我尝试使用 pip install yum
也不能重新安装 yum。
我在网上搜了很多解决yum无法使用的问题的文章,绝大部分文章都虎头蛇尾,没有根本解决问题,后来找到下面一文给我提供灵感:
十分感谢博主“就想做一条闲鱼”。
上面报错信息中提及 /usr/lib64/python2.7/site-packages/pycurl.so
这个文件,我们查看一下这个文件的情况。
CRYPTO_num_locks
是 OpenSSL 库中的一个函数,用于处理加密操作中的锁管理。
在某些版本的OpenSSL中,CRYPTO_num_locks
函数用于获取需要的锁数量,以确保线程安全。
这个函数在多线程应用中尤为重要,因为它帮助管理对加密操作的并发访问。
pycurl.so
是pycurl
库的共享对象文件,它是libcurl
的 Python 绑定。
pycurl 库用于在 Python 中执行 URL 请求和数据传输,底层依赖 libcurl 库,而 libcurl 又依赖于 OpenSSL 库来处理 HTTPS 连接和加密操作。
1、查看依赖关系
ldd /usr/lib64/python2.7/site-packages/pycurl.so
输出内容类似:
linux-vdso.so.1 => (0x00007ffd0d9fe000)
libcurl.so.4 => /usr/local/lib/libcurl.so.4 (0x00007f0ddb670000)
libpython2.7.so.1.0 => /lib64/libpython2.7.so.1.0 (0x00007f0ddb2a4000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f0ddb088000)
libc.so.6 => /lib64/libc.so.6 (0x00007f0ddacba000)
libnghttp2.so.14 => /lib64/libnghttp2.so.14 (0x00007f0ddaa92000)
libssl.so.10 => /lib64/libssl.so.10 (0x00007f0dda820000)
libcrypto.so.10 => /lib64/libcrypto.so.10 (0x00007f0dda3bd000)
......
上面提及 pycurl.so
与 libcurl
息息相关,我把命令改一下:
ldd /usr/lib64/python2.7/site-packages/pycurl.so | grep "libcurl"
筛选出下面的信息:
2、查看 libcurl 相关的文件
执行命令:
ll /usr/local/lib/libcurl*
结果显示:
由此可见,系统中存在多个版本的 libcurl 库,包括 libcurl.so.4.7.0、libcurl.so.4.8.0,以及相应的符号链接(libcurl.so和libcurl.so.4)。
忽然想起来我就是不久前反复安装不同版本的 curl,可能导致 pycurl.so 链接到错误版本的libcurl,引发 yum 无法使用,报出 undefined symbol: CRYPTO_num_locks
错误。
3、删除链接文件
cd /usr/local/lib
rm -rf libcurl.so
rm -rf libcurl.so.4
至此,CentOS 的 yum 命令就恢复正常了!
这种问题通常是由库文件冲突或不兼容引起的,解决方法是确保程序加载的是系统默认的库文件,避免自定义安装的库文件干扰系统工具的运行。
2024年8月7日更新
最近使用 yum upgrade 命令时总是报错:
Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=os&infra=stock error was
14: curl#6 - "Could not resolve host: mirrorlist.centos.org; Unknown error"
One of the configured repositories failed (Unknown),
and yum doesn't have enough cached data to continue. At this point the only
safe thing yum can do is fail. There are a few ways to work "fix" this:
1. Contact the upstream for the repository and get them to fix the problem.
2. Reconfigure the baseurl/etc. for the repository, to point to a working
upstream. This is most often useful if you are using a newer
distribution release than is supported by the repository (and the
packages for the previous distribution release still work).
3. Run the command with the repository temporarily disabled
yum --disablerepo=<repoid> ...
4. Disable the repository permanently, so yum won't use it by default. Yum
will then just ignore the repository until you permanently enable it
again or use --enablerepo for temporary usage:
yum-config-manager --disable <repoid>
or
subscription-manager repos --disable=<repoid>
5. Configure the failing repository to be skipped, if it is unavailable.
Note that yum will try to contact the repo. when it runs most commands,
so will have to try and fail each time (and thus. yum will be be much
slower). If it is a very temporary problem though, this is often a nice
compromise:
yum-config-manager --save --setopt=<repoid>.skip_if_unavailable=true
Cannot find a valid baseurl for repo: base/7/x86_64
原因是自2024年7月1日起,CentOS 7 的 yum 命令开始改用 Vault
仓库,因此需要运行下面的命令修改配置文件:
nano /etc/yum.repos.d/CentOS-Base.repo
按 Ctrl+K 删除该文件所有行,然后粘贴下面的内容:
[base]
name=CentOS-$releasever - Base
baseurl=http://vault.centos.org/7.9.2009/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
[updates]
name=CentOS-$releasever - Updates
baseurl=http://vault.centos.org/7.9.2009/updates/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
[extras]
name=CentOS-$releasever - Extras
baseurl=http://vault.centos.org/7.9.2009/extras/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
[centosplus]
name=CentOS-$releasever - Plus
baseurl=http://vault.centos.org/7.9.2009/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
按 Ctrl + O 保存、Ctrl + X 退出 nano。此时运行 yum upgrade
恢复正常更新。