; TL-DR - Resposta: porque o vinculador dinâmico ld-linux-x86-64.so.2 estava faltando.
Eu montei um sistema de arquivos squashfs (não importa) -ro,loop
at /mnt/foo
.
Ele contém, entre outras coisas, o seguinte ( /mnt/foo
é o ponto de montagem):
-rwxr-xr-x 1 root root 110088 jan 17 2013 /mnt/foo/bin/ls
-rw-r--r-- 1 root root 5212 jul 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 root root 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 root root 256224 mar 11 2013 /mnt/foo/lib/libpcre.so.3
-rwxr-xr-x 1 root root 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
contém uma única linha (incluindo nova linha) com apenas /lib
.
Antes de criar o sistema de arquivos, executei ldconfig -r ${TOPDIR}
onde ${TOPDIR}
resolvido para o local que agora está montado em /mnt/foo
.
Um strings
on /mnt/foo/etc/ld.so.cache
mostra que ele contém strings como /lib/libpcre.so.3
e assim por diante, então não acho que seja um problema com as bibliotecas compartilhadas.
Eu acho que deve ser algo bobo que eu estou negligenciando, mas eu não consigo entender por que um simples chroot /mnt/foo /bin/ls
não funciona.
readelf -d /mnt/foo/bin/ls | grep NEEDED
mostra essas bibliotecas conforme necessário:
0x0000000000000001 (NEEDED) Shared library: [libselinux.so.1]
0x0000000000000001 (NEEDED) Shared library: [librt.so.1]
0x0000000000000001 (NEEDED) Shared library: [libacl.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
Por fim, strace
mostra isso:
chroot("/mnt/foo") = 0
chdir("/") = 0
execve("/bin/ls", ["/bin/ls"], [/* 32 vars */]) = -1 ENOENT (No such file or directory)
Este é o chroot de strace completo:
# 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 (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc115ac8000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/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
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "7ELF
-rwxr-xr-x 1 root root 110088 jan 17 2013 /mnt/foo/bin/ls
-rw-r--r-- 1 root root 5212 jul 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 root root 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 root root 256224 mar 11 2013 /mnt/foo/lib/libpcre.so.3
-rwxr-xr-x 1 root root 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
0x0000000000000001 (NEEDED) Shared library: [libselinux.so.1]
0x0000000000000001 (NEEDED) Shared library: [librt.so.1]
0x0000000000000001 (NEEDED) Shared library: [libacl.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
chroot("/mnt/foo") = 0
chdir("/") = 0
execve("/bin/ls", ["/bin/ls"], [/* 32 vars */]) = -1 ENOENT (No such file or directory)
# 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 (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc115ac8000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/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
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "7ELF%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%>%pre%%pre%%pre%%pre%0%pre%%pre%%pre%%pre%%pre%"..., 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
close(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
open("/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
close(3) = 0
chroot("/mnt/foo") = 0
chdir("/") = 0
execve("/bin/ls", ["/bin/ls"], [/* 32 vars */]) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale-langpack/en_US/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale-langpack/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/charset.alias", O_RDONLY|O_NOFOLLOW) = -1 ENOENT (No such file or directory)
write(2, "chroot: ", 8chroot: ) = 8
write(2, "failed to run command 200/bin/ls"..., 35failed to run command ‘/bin/ls’) = 35
open("/usr/share/locale/en_US/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale-langpack/en_US/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale-langpack/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
write(2, ": No such file or directory", 27: No such file or directory) = 27
write(2, "\n", 1
) = 1
close(1) = 0
close(2) = 0
exit_group(127) = ?
+++ exited with 127 +++
%pre%%pre%%pre%%pre%%pre%%pre%>%pre%%pre%%pre%%pre%0%pre%%pre%%pre%%pre%%pre%"..., 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
close(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
open("/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
close(3) = 0
chroot("/mnt/foo") = 0
chdir("/") = 0
execve("/bin/ls", ["/bin/ls"], [/* 32 vars */]) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale-langpack/en_US/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale-langpack/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/charset.alias", O_RDONLY|O_NOFOLLOW) = -1 ENOENT (No such file or directory)
write(2, "chroot: ", 8chroot: ) = 8
write(2, "failed to run command 200/bin/ls"..., 35failed to run command ‘/bin/ls’) = 35
open("/usr/share/locale/en_US/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale-langpack/en_US/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale-langpack/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
write(2, ": No such file or directory", 27: No such file or directory) = 27
write(2, "\n", 1
) = 1
close(1) = 0
close(2) = 0
exit_group(127) = ?
+++ exited with 127 +++
Então, isso é ENOENT
enganoso?
YES - ENOENT é um pouco enganador. Para mim sempre significou "arquivo não encontrado".
Quando o vinculador dinâmico não pode ser encontrado, o execve () obtém ENOENT.
Quando o kernel de inicialização tenta carregar init
(ou linuxrc ou qualquer outro), o erro que recebo é " Falha ao executar / linuxrc (erro -2). Tentando padrões ... " .
O problema aconteceu devido a um bug no meu script que criou esse ramdisk inicial. (omitiu bibliotecas não apontadas por "= >" por ldd
).
Duas perguntas bônus para ponderar créditos extras:
- o que é
linux-vdso.so.1
que ldd
mostra sem um caminho?
- por que
ldd
mostra ld-linux.so sem um " =>
"?