为什么 chroot 在现有文件上得到 ENOENT?

为什么 chroot 在现有文件上得到 ENOENT?

;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 stringson/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

相关内容