LD_LIBRARY_PATH导致update-initramfs后找不到库的错误

LD_LIBRARY_PATH导致update-initramfs后找不到库的错误

背景

本文需要对linux引导启动过程有一定的了解

最近在linux上要实现类似于冰点还原的功能,需要借助aufs文件操作系统来实现,而这种类型的驱动模块安装后要重新制作initramfs引导。所以需要在程序中自动的修改系统引导。

但是在开发的过程中发现如果使用自己的程序调用脚本修改系统引导会导致系统无法启动,引导阶段提示systemd-udev在启动的时候找不到libcrypto.so。而如果直接在shell里调用脚本,不通过自己的程序调用则没问题。

最后经过控制变量法对比发现,是因为自己的程序在启动时使用了LD_LIBRARY_PATH环境变量导致,如果不使用则没有问题。

原因

首先,问题表现在systemd-udev,而systemd-udev是系统的功能,我自己肯定是没有修改的,而报告的是找不到库,那么问题可能就是制作引导的时候把库漏掉了,在引导失败后进入initramfs系统,发现确实找不到libcrypto.so库。

那么只有去看一下制作引导系统的时候是怎么拷贝库的。制作引导系统是通过系统提供的update-initramfs脚本。经过阅读update-initramfs的源码后终于发现了端倪。

update-initramfs使用一个copy_exec的函数来负责把当前系统中用来初始化系统的关键程序拷贝到一个和当前系统路径一致的虚拟路径中,然后制作成镜像文件。

而因为通常程序都会依赖一些动态库,所以拷贝的时候需要将这些程序依赖的动态库一起拷贝过去。copy_exec使用ldd命令来检查程序依赖的动态库。但是显然我们知道ldd命令的结果是受到LD_LIBRARY_PATH环境变量影响的。

刚好自己的程序为了能够寻找到自己的依赖库使用了LD_LIBRARY_PATH环境变量,而且恰好自己的LD_LIBRARY_PATH环境变量路径中有libcrypto.so这个动态库,这就导致在自己的程序中制作initramfs引导时copy_execLD_LIBRARY_PATH的影响拷贝了其他路径中libcrypto.so,而initramfs引导系统中并没有人来设置LD_LIBRARY_PATH环境变量,这就导致systemd-udev无法在默认的库路径中找到libcrypto.so了。

解决

知道了原因后解决方案也就很明显了,在调用update-initramfs脚本前,清除所有对ldd命令造成影响的设置,例如LD_LIBRARY_PATH环境变量之类的。

你可能感兴趣的:(linux,linux)