;TL-DR-回答:因为动态链接器 ld-linux-x86-64.so.2 丢失。
我已经-ro,loop
在/mnt/foo
.
它包含以下内容(/mnt/foo
是挂载点):
-rwxr-xr-x 1 根根 110088 2013 年 1 月 17 日 /mnt/foo/bin/ls -rw-r--r-- 1 root root 5212 七月 23 09:35 /mnt/foo/etc/ld.so.cache -rw-r--r-- 1 root root 5 jul 23 09:35 /mnt/foo/etc/ld.so.conf -rw-r--r-- 1 root root 31168 maj 23 2013 /mnt/foo/lib/libacl.so.1 -rw-r--r-- 1 root root 18624 maj 20 2013 /mnt/foo/lib/libattr.so.1 -rwxr-xr-x 1根根1853400 okt 12 2013 /mnt/foo/lib/libc.so.6 -rw-r--r-- 1 root root 14664 okt 12 2013 /mnt/foo/lib/libdl.so.2 -rw-r--r-- 1根根256224 2013年3月11日/mnt/foo/lib/libpcre.so.3 -rwxr-xr-x 1根根135757 okt 12 2013 /mnt/foo/lib/libpthread.so.0 -rw-r--r-- 1 root root 31760 okt 12 2013 /mnt/foo/lib/librt.so.1 -rw-r--r-- 1 root root 134224 maj 23 2013 /mnt/foo/lib/libselinux.so.1
/mnt/foo/etc/ld.so.conf
包含一行(包括换行符)/lib
。
在创建文件系统之前,我将ldconfig -r ${TOPDIR}
whereresolved运行${TOPDIR}
到现在安装在的位置/mnt/foo
。 A strings
on/mnt/foo/etc/ld.so.cache
显示它包含诸如此类的字符串/lib/libpcre.so.3
,所以我认为这不是共享库的问题。
我想这一定是我忽略的一些愚蠢的事情,但是我无法弄清楚为什么简单的方法chroot /mnt/foo /bin/ls
不起作用。
readelf -d /mnt/foo/bin/ls | grep NEEDED
根据需要显示这些库:
0x0000000000000001(需要)共享库:[libselinux.so.1] 0x0000000000000001(需要)共享库:[librt.so.1] 0x0000000000000001(需要)共享库:[libacl.so.1] 0x0000000000000001(需要)共享库:[libc.so.6]
最后,strace
展示一下:
chroot("/mnt/foo") = 0 chdir("/") = 0 execve("/bin/ls", ["/bin/ls"], [/* 32 vars */]) = -1 ENOENT (没有这样的文件或目录)
这是完整的 strace chroot:
# strace -f chroot /mnt/foo /bin/ls execve("/usr/sbin/chroot", ["chroot", "/mnt/foo", "/bin/ls"], [/* 32 vars */]) = 0 brk(0) = 0x1985000 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT(没有这样的文件或目录) mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc115ac8000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT(没有这样的文件或目录) 打开(“/etc/ld.so.cache”,O_RDONLY | O_CLOEXEC)= 3 fstat(3, {st_mode=S_IFREG|0644, st_size=96457, ...}) = 0 mmap(NULL, 96457, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fc115ab0000 关闭(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT(没有这样的文件或目录) 打开(“/lib/x86_64-linux-gnu/libc.so.6”,O_RDONLY | O_CLOEXEC)= 3 读(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360\36 \2\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=1853400, ...}) = 0 mmap(NULL, 3961912, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fc1154e0000 mprotect(0x7fc11569d000, 2097152, PROT_NONE) = 0 mmap(0x7fc11589d000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1bd000) = 0x7fc11589d000 mmap(0x7fc1158a3000, 17464, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fc1158a3000 关闭(3) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc115aaf000 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc115aad000 arch_prctl(ARCH_SET_FS, 0x7fc115aad740) = 0 mprotect(0x7fc11589d000, 16384, PROT_READ) = 0 mprotect(0x606000, 4096, PROT_READ) = 0 mprotect(0x7fc115aca000, 4096, PROT_READ) = 0 munmap(0x7fc115ab0000, 96457) = 0 brk(0) = 0x1985000 brk(0x19a6000) = 0x19a6000 打开(“/ usr / lib / locale / locale-archive”,O_RDONLY | O_CLOEXEC)= 3 fstat(3, {st_mode=S_IFREG|0644, st_size=8463952, ...}) = 0 mmap(NULL, 8463952, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fc114ccd000 关闭(3) = 0 chroot("/mnt/foo") = 0 chdir("/") = 0 execve("/bin/ls", ["/bin/ls"], [/* 32 vars */]) = -1 ENOENT (没有这样的文件或目录) open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = -1 ENOENT(没有这样的文件或目录) open("/usr/share/locale/en_US/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (没有这样的文件或目录) open("/usr/share/locale/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (没有这样的文件或目录) open("/usr/share/locale-langpack/en_US/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT(没有这样的文件或目录) open("/usr/share/locale-langpack/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (没有这样的文件或目录) open("/usr/lib/charset.alias", O_RDONLY|O_NOFOLLOW) = -1 ENOENT(没有这样的文件或目录) 写(2,“chroot:”,8chroot:)= 8 write(2, "无法运行命令 \342\200\230/bin/ls"..., 35无法运行命令 '/bin/ls') = 35 open("/usr/share/locale/en_US/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (没有这样的文件或目录) open("/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (没有这样的文件或目录) open("/usr/share/locale-langpack/en_US/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (没有这样的文件或目录) open("/usr/share/locale-langpack/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (没有这样的文件或目录) write(2, ": 没有这样的文件或目录", 27: 没有这样的文件或目录) = 27 写(2, "\n", 1 ) = 1 关闭(1) = 0 关闭(2) = 0 退出组(127)=? +++ 以 127 退出 +++
那么,这是否ENOENT
具有误导性?
是的 - ENOENT 有点误导。对我来说,它始终意味着“找不到文件”。
当找不到动态链接器时,execve() 得到 ENOENT。
当引导内核尝试加载init
(或 linuxrc 或其他)时,我得到的错误是“无法执行 /linuxrc(错误 -2)。尝试默认...”。
该问题的发生是由于创建此初始 ramdisk 的脚本中的错误所致。 (它省略了“=>”未指出的库ldd
)。
为了获得额外学分,需要思考两个额外问题:
- 没有路径显示
linux-vdso.so.1
什么?ldd
- 为什么
ldd
显示 ld-linux.so 时没有“=>
”?
答案1
问题是/bin/ls
不仅仅需要您提供的共享库。它还需要加载它们的程序; Linux 加载器。
要解决您的问题,您可以将加载程序从您的系统(通常/lib/ld-linux.so.2
)复制到 chroot ( ) 的位置/mnt/foo/lib/ld-linux.so.2
。