升级glibc引发的故障

为了安装promtail日志采集工具,提示我需要升级glibc到2.34版本。也许是对于这次升级的自信,因为之前也升级过,并无问题。没想到系统的不同升级glibc带来的影响也不同。而且这次升级编译安装时候并未指定单独的prefix目录。导致 make install 后出了问题,几乎所有的系统命令无法使用。如 rm、ls、mv 等均提示 Segmentation fault (core dumped) ,也无法再次ssh登录设备。没错出问题的正式我的博客服务器。身为一名运维,得有一个临危不乱的心态。下面就说说我解决这个问题的方式。

glibc介绍

glibc是什么?为什么升级风险这么高?glibc的作用是什么?

glibc是GNU发布的libc库,即c运行库。glibc是linux系统中最底层的api,几乎其它任何运行库都会依赖于glibc。glibc除了封装linux操作系统所提供的系统服务外,它本身也提供了许多其它一些必要功能服务的实现。内核实现一个功能,glibc要花很久才会用上,由于glibc和内核不是一块开发的,所以glibc需要去兼容不同版本的内核,而内核也要去兼容不同版本的 glibc,双方都背负了太多的历史包袱。

简单理解其实和http api接口类似,区别在于glibc是调用内核对底层磁盘,内存,网卡等的操作,http api则是对应用层app的操作,比如听一首歌,下载一部电影实则都是在调用http api接口。

问题复现

[root@blog ~]# wegt https://mirror.fcix.net/gnu/glibc/glibc-2.34.tar.gz
[root@blog ~]# tar -xf glibc-2.34.tar.gz && cd glibc-2.34
[root@blog glibc-2.34]# mkdir build install
[root@blog build]# cd build
[root@blog build]# ../glibc-2.34/configure --prefix=/usr
[root@blog build]# make
[root@blog build]# make install
# make install DESTDIR=/xxx/xxx/install 在install时候使用DESDIR指定安装目录会覆盖configure时候prefix指定的安装目录。

到此安装完以后系统命令就开始无法使用了,但是正在运行中的进程是正常的。因为正在运行的进程在启动时候就以将glibc加载到内存使用,也就是老版本正常的glibc。但是当我们执行ls命令等,则是刚运行的将会调用最新的glibc 就无法正常执行。报错如下:

[root@blog lib64]# ls
Segmentation fault (core dumped)

解决思路

抢救要求

此时就算如上报错,业务任然是正常的。所以千万慌张,还不能瞎动。如果不想影响业务,务必做到以下两点:

  • 不要重启服务器,重启不光影响业务。服务器启动时候也是启动不起来的。

  • 不要断开此时的ssh连接,因为这时候这个连接已是唯一还能操作这台服务器的。

    如果不满足以上两点,那不好意思业务得断了。必须进入系统安全模式处理。安全模式下处理我就不介绍了。

实施抢救

问题出在新版本的glibc,那就想办法将版本回退。这里我推荐大家使用finalshell,也正是FinalShell拯救了我!从FinalShell中我们依然可以查到,libc的历史版本是2.28。每个操作系统情况可能不一样,建议查看文件修改时间,看下其他库文件是否也更新了。(图中是我已回退的库文件)

image-20240715215206368
[root@blog lib64]# ldconfig -lv /usr/lib64/libc-2.28.so 
ldconfig: /usr/lib64/libc.so.6 is not a symbolic link
# 尝试手动重新链接旧的库文件,结果报错,很明显新版本的 libc.so.6 文件占坑了。那就把它删了。

[root@blog lib64]# rm -f libc.so.6
Segmentation fault (core dumped)
[root@blog lib64]# rm -rf libc.so.6
Segmentation fault (core dumped)
[root@blog lib64]# mv libc.so.6 /opt/
Segmentation fault (core dumped)
# 一通操作也无法将其删除,最后还得靠FinalShell,我尝试在如上图中右键删除,还真给删除了。

[root@blog lib64]# ldconfig -lv /usr/lib64/libc-2.28.so 
        libc.so.6 -> libc-2.28.so (changed)
# 当再次尝试手动重新链接旧的库文件,已正常链接。其他命令也都恢复了正常、ssh也能正常登录,危机解除。

术后小结

  1. 生产环境glibc不要随便乱升。
  2. 就算要升级,编译前configure请指定一个自定义目录,不要用系统目录。或者install时候务必指定一个自定义目录。再去 /etc/ld.so.conf.d/ 目录中手动配置库文件进行加载,这样就算有问题也好处理,删除配置重启系统就能解决。
  3. 推荐使用FinalShell,真心不错。缺点就是java开发的,有点吃内存。

本文由 mdnice 多平台发布

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值