¿Por qué no puedo crear un "enlace duro" a un archivo desde un directorio "mount --bind" en el mismo sistema de archivos?

9

Problema original

Tengo un archivo en un sistema de archivos: /data/src/file

y quiero vincularlo a: /home/user/proj/src/file

pero /homeestá en un disco y /dataestá en otro, así que recibo un error:

$ cd /home/user/proj/src
$ ln /data/src/file .
ln: failed to create hard link './file' => '/data/src/file': Invalid cross-device link

Bien, entonces aprendí que no puedo vincular a través de dispositivos. Tiene sentido.

Problema a mano

Así que pensé en ponerme elegante y montar una srccarpeta que está en /datael sistema de archivos:

$ mkdir -p /data/other/src
$ cd /home/user/proj
$ sudo mount --bind /data/other/src src/
$ cd src
$ # (now we're technically on `/data`'s file system, right?)
$ ln /data/src/file .
ln: failed to create hard link './file' => '/data/src/file': Invalid cross-device link

¿Por qué esto todavía no funciona?

Solución alterna

Sé que tengo esta configuración correcta porque puedo hacer el enlace duro siempre que esté en el /datadirectorio "real" en lugar del enlazado.

$ cd /data/other/src
$ ln /data/src/file .
$ # OK
$ cd /home/user/proj/src
$ ls -lh
total 35M
-rw------- 2 user user 35M Jul 17 22:22 file

$

Alguna información del sistema

$ uname -a
Linux <host> 4.10.0-24-generic #28-Ubuntu SMP Wed Jun 14 08:14:34 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

$ findmnt
.
.
.
├─/home                               /dev/sdb8   ext4       rw,relatime,data=ordered
│ └─/home/usr/proj/src             /dev/sda2[/other/src]
│                                                 ext4       rw,relatime,data=ordered
└─/data                               /dev/sda2   ext4       rw,relatime,data=ordered

$ mountpoint -d /data
8:2

$ mountpoint -d /home/usr/proj/src/
8:2

Nota : Cambié manualmente los nombres de archivo y directorio para aclarar la situación, por lo que puede haber un error tipográfico o dos en las lecturas de comandos.

jdk1.0
fuente
2
No importa dónde monte la carpeta. Son físicos en diferentes particiones. Cada partición tiene su propia tabla de archivos y el enlace duro solo se registra en esta tabla.
user996142
2
El punto aquí es que los archivos NO están en particiones físicamente diferentes. Es el mismo sistema de archivos de la misma partición. La diferencia es el montaje de unión.
roaima
La montura de unión es simplemente una ficción. No cambia las estructuras de datos en los discos. Los sistemas de archivos aún están físicamente separados.
Bob Eager
Pero cuando creo el enlace duro en /datapuedo acceder al inodo desde el directorio de montaje de enlace, por lo que el montaje de enlace debe estar en la misma partición /datao el enlace duro funciona en todos los dispositivos, lo que debería ser ilegal, pero funciona de todos modos. ¿Qué me estoy perdiendo?
jdk1.0

Respuestas:

6

Hay una falta decepcionante de comentarios en el código . Es como si a nadie le hubiera parecido útil, ya que los montajes de enlace de tiempo se implementaron en v2.4. Seguramente todo lo que necesita hacer es sustituir .mnt->mnt_sbdonde dice .mnt...

Porque le da un límite de seguridad alrededor de un subárbol.

PD: eso se discutió varias veces, pero para evitar búsquedas: considere, por ejemplo, mount --bind / tmp / tmp; ahora tiene una situación en la que los usuarios no pueden crear enlaces a otras partes que no tengan raíz fs, aunque tengan / tmp grabable. Técnicas similares funcionan para otras necesidades de aislamiento: básicamente, puede limitar el cambio de nombre / enlace a un subárbol dado. IOW, es una característica deliberada. Tenga en cuenta que puede atar un grupo de árboles en chroot y obtener restricciones predecibles independientemente de cómo se reorganicen las cosas un año después en el árbol principal, etc.

- Al Viro

Hay un ejemplo concreto más abajo en el hilo

Cada vez que hacemos que mount -r --bind funcione correctamente (lo cual uso para colocar copias de las bibliotecas compartidas necesarias dentro de las cárceles chroot mientras se permite compartir la memoria caché de la página), esta característica rompería la seguridad.

mkdir /usr/lib/libs.jail
for i in $LIST_OF_LIBRARIES; do
ln /usr/lib/$i /usr/lib/libs.jail/$i
done
mount -r /usr/lib/libs.jail /jail/lib
chown prisoner /usr/log/jail
mount /usr/log/jail /jail/usr/log
chrootuid /jail prisoner /bin/untrusted &

Aunque las protecciones deberían ser suficientes, prefiero evitar que el prisionero enlace /jail/lib/libfoo.so (escribir devuelve EROFS) a / jail / usr / log donde es potencialmente escribible.

sourcejedi
fuente
-1

La razón por la que no puede hacer enlaces entre dispositivos es porque introduce ambigüedades. La entrada de directorio para el archivo contiene (en sistemas simples) el número de i-nodo para el archivo en cuestión. Un enlace rígido (solo otra entrada de directorio) también debe contener el mismo número de i-nodo. Esto está bien, pero los números de i-node solo son únicos dentro de un solo sistema de archivos (generalmente son un conjunto denso que comienza en 1).

Su montaje de enlace no soluciona ese problema. Sí, construye una especie de 'ficción' de la estructura, pero lo que no hace es volver a numerar todos los nodos-i en un sistema de archivos para asegurarse de que sean únicos en los dos sistemas de archivos en cuestión. Eso sería una tontería.

Esta restricción siempre ha estado presente en los sistemas UNIX. El enlace simbólico fue inventado en parte para resolver esto. Sé que no son funcionalmente iguales, pero generalmente están bien.

Prueba un enlace simbólico? ( ln -s)

Bob ansioso
fuente
No habría nombre para ningún renumeración de inodo aquí. Solo hay un sistema de archivos subyacente, con dos vistas.
Gilles 'SO- deja de ser malvado'
Una razón por la que no quería un enlace simbólico era porque mis caminos eran largos y era complicado hacer un ls -l. Razonamiento tonto un poco al principio, pero luego se conduce a un agujero de conejo y me dio curiosidad sobre lo que estaba pasando con los enlaces duros ...
jdk1.0
@Gilles, eso es lo que estaba diciendo. El punto que estaba señalando era que la renumeración de inodes sería ridícula. No tengo idea de por qué se rechazó una respuesta correcta.
Bob Eager
La conclusión es correcta, pero su explicación es incorrecta en tantos lugares que su respuesta en su conjunto es muy engañosa. Ver la respuesta de sourcejedi para una buena explicación.
Gilles 'SO- deja de ser malvado'
No veo ningún error en absoluto, aunque admito que podría haber sido más claro.
Bob Eager