【救火】误动libc.so.6的补救措施

  国庆假期闲来无事,对自己的群晖 NAS(非生产环境) 内的一个内置软件包做编译升级。在不明确该动态库具体作用的情况下,误操作将 /lib/libc.so.6 这个动态库文件重命名为了 libc.so.6.bak,导致 lsmvcp 等一系列基础命令无法使用,本文记录一下解决方案。

症状表现

  在执行完(切勿作死!!!) mv /lib/libc.so.6 /lib/libc.so.6.bak 的一瞬间,终端便报错:

1
2
3
mv /lib/libc.so.6 /lib/libc.so.6.bak
whoami: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory
logger: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory

  想执行 mv 将其重新命名回来的时候,已经无济于事。大部分的命令均报 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory 错误。

解决方案

  首先,如果是生产环境遇到这种情况,在没有明确解决办法的情况下,请第一时间停止一切操作,不要退出终端。

未退出终端的情况下

  这种情况比较简单,利用 LD_PRELOAD 这个环境变量来指定正确的动态库,再执行命令即可

LD_PRELOAD是Linux系统的一个环境变量,它可以影响程序的运行时的链接(Runtime linker),它允许你定义在程序运行前优先加载的动态链接库。这个功能主要就是用来有选择性的载入不同动态链接库中的相同函数。通过这个环境变量,我们可以在主程序和其动态链接库的中间加载别的动态链接库,甚至覆盖正常的函数库。一方面,我们可以以此功能来使用自己的或是更好的函数(无需别人的源码),而另一方面,我们也可以以向别人的程序注入程序,从而达到特定的目的。

1
LD_PRELOAD=/lib/libc.so.6.bak mv /lib/libc.so.6.bak /lib/libc.so.6

已退出终端或重启

  这种情况下就比较麻烦,需要使用光盘镜像刻录的启动U盘,进入救援模式,挂载硬盘分区来进行修复了。(部分系统原有 SELinux 的,修改前需要关闭 SELinux,否则无法启动)

群晖解决方案

  首先需要明白的是,群晖的系统存在于每块磁盘上的第一个分区,文件系统类型为 ext4,因此,当我们需要修改系统文件的时候,需要对每块磁盘都进行修改。
  将磁盘挂载到 CentOS(其他你更为熟悉的发行版均可),通过 lsblk 查看磁盘的分区情况。将磁盘的第一块分区使用 mount -t ext4 /dev/xx(分区设备名)/mnt 的方式挂载,再进行修改即可。(群晖貌似是没开SELinux的,所以直接修改文件也不会有大坑)。修改完后别忘记 umount 防止出现数据损坏。
  待所有盘都修改完成后,再全部插入到群晖中开机。
  如果要恢复数据文件,则在第三个分区。用以上方式同理(数据文件一般为 btrfs 文件系统类型)即可。倘若你的存储空间为 SHR 模式,则需先安装 mdadm 来还原软 RAID:

1
mdadm -Asf && vgchange -ay

这时候会提示生成了阵列drive,直接对其挂载即可:

1
mount -t btrfs /dev/mdx(上一步提示的) /mnt