¿Cómo es capaz findmnt de enumerar montajes de enlace?

11

Mucha gente sigue diciendo que Linux no guarda información sobre los montajes de enlace, por lo que no hay forma de obtener una lista de ellos y sus fuentes. Aquí hay unos ejemplos:

  • de uno de los comentarios aquí :

    IIRC esta información no se guarda en ningún lado: después mount --bind, las dos copias son equivalentes, no hay una que sea más "original" que la otra. Después de todo, no podría haber original si ya hubiera desmontado /mnt.

  • de una respuesta en este sitio :

    Entonces, la única forma de recordar qué monturas eran monturas de unión es el registro de los comandos de montura que quedan /etc/mtab. Una operación de montaje de enlace se indica mediante la opción de montaje de enlace (que hace que se ignore el tipo de sistema de archivos). Pero mount no tiene la opción de enumerar solo los sistemas de archivos montados con un conjunto particular de conjuntos de opciones.

  • de un informe de error de Debian :

    Esto es intencional Ambos puntos de montaje son totalmente iguales en todos los sentidos, por lo que el núcleo no mantiene ningún indicador para diferenciarlos.

Sin embargo, lo anterior no tiene sentido. La herramienta findmntpuede enumerar las rutas de origen de los montajes de enlace (en forma de device[source-path]; También estoy tratando de hacer que solo enumere la ruta de origen y no el dispositivo). Si el kernel de Linux va a mantener un montaje de enlace, entonces esa información tiene que almacenarse en algún lugar , de lo contrario no podría saber que /homeestá vinculada /users. Entonces, ¿dónde están estos datos? ¿Está almacenado en alguna región oscura en la RAM? ¿ findmntMira en /procalgún lado?

Melab
fuente
¿Qué versión de findmntestá ejecutando y qué opciones le está dando? El mío no lo imprime así y mirando el código fuente que parece estar usando, _PATH_PROC_MOUNTINFOque parece /proc/self/mountinfono tener esta información tampoco.
Bratchley
OK, supongo que /proc/self/mountinforelativamente recientemente fue reestructurado. Estaba en mi máquina RHEL6 antes, que no tenía la información de la ruta, pero mi máquina RHEL7 sí y, como se menciona en su enlace, Wheezy también.
Bratchley
No es una tontería: era cierto con los núcleos más antiguos, pero los núcleos más nuevos rastrean la información.
Gilles 'SO- deja de ser malvado'
@Gilles Entonces, ¿cómo podría persistir un montaje de enlace si no se rastrea la información de que un directorio está montado en otro?
Melab
@Melab En realidad, es más fácil que una montura de enlace persista si no realiza un seguimiento de que es una montura de enlace. Cuando /dev/Ase monta en /By lo hace mount --bind /B /C, los núcleos más antiguos solo recuerdan /B → /dev/Ay /C → /dev/A, no recuerdan ninguna relación entre /By /C. Por lo tanto, desmontar /Bnaturalmente no tiene ningún efecto /C. Los núcleos más nuevos recuerdan que /Cfue un montaje de enlace /B, pero de una manera que no impide /Ccontinuar trabajando si no /Bestá montado, no sé exactamente cómo.
Gilles 'SO- deja de ser malvado'

Respuestas:

12

Has malentendido un poco; los dos puntos de montaje son iguales en términos de permisos, banderas, etc. porque el enlace redirige efectivamente el acceso de una ruta a otra. Pero todavía son distintos .

Si observa /proc/self/mountinfo, verá la vista del núcleo del mundo de montaje para este proceso (los espacios de nombres hacen las cosas más complicadas; no hay una sola vista de la tabla de montaje).

man 5 procexplicará el formato de este archivo, pero puede ver la jerarquía del árbol y dónde los montajes de enlace tienen su "padre". Este es el archivo que findmntanaliza.

Stephen Harris
fuente
9

Linux no mantiene la información sobre qué montaje era un montaje de enlace . Mantiene información sobre todas las monturas, incluidas las monturas de enlace .

Es bastante similar a los enlaces duros. Los montajes enlazan a sistemas de archivos como los nombres de archivos enlazan a inodes. Las únicas diferencias son que los montajes también tienen indicadores por punto de montaje y pueden referirse a un subdirectorio del sistema de archivos de destino en lugar de la raíz del sistema de archivos.

Cuando crea un enlace duro, el sistema de archivos no guarda qué nombre de archivo era el original y cuál era el enlace duro. Ambos simplemente se refieren al mismo inodo. Si desvincula el archivo original, la situación no se puede distinguir si creó directamente el archivo con el segundo nombre de archivo.

Regresar a los montajes de enlace: el núcleo mantiene una tabla que contiene el sistema de archivos (identificado por un par mayor: número menor), el punto de montaje, la ruta relativa a la raíz del sistema de archivos y algunos indicadores. Puede acceder a esta lista mirando /proc/self/mountinfo. (Se vuelve más complicado cuando hay espacios de nombres involucrados, como mencionó @ stephen-harris). findmntanaliza esta lista.

Si su raíz es /dev/sda1con el mayor: menor 8:1y ejecuta mount --bind /a /b /proc/self/mountinfocontendrá líneas similares a esta:

1 0 8:1 / / rw - ext4 /dev/sda1 rw,errors=remount-ro
2 1 8:1 /a /b rw - ext4 /dev/sda1 rw,errors=remount-ro

Si /homeestá /dev/sda2con el mayor: menor 8:2y ejecuta mount --bind /home /users, se verá así:

1 0 8:1 / / rw - ext4 /dev/sda1 rw,errors=remount-ro
2 1 8:2 / /home rw - ext4 /dev/sda2 rw
3 1 8:2 / /users rw - ext4 /dev/sda2 rw

Las columnas relevantes para su pregunta son la tercera, la cuarta y la quinta. Esta es la identificación del sistema de archivos (para sistemas de archivos reales es lo mismo que el dispositivo mayor: menor; para sistemas de archivos virtuales como tmpfs es [0: contador ]), la ruta relativa a la raíz del sistema de archivos que está vinculada al punto de montaje (generalmente / para normal monturas, puede ser cualquier cosa para monturas de unión) y el punto de montaje.
Para conocer el significado de las columnas restantes, consulte la documentación del kernel de Linux .

findmntllama a la ruta de origen relativa a la raíz del sistema de archivos "FSROOT". Puedes usar findmnt -o TARGET,FSROOTpara conseguirlo. Si desea la ruta de origen absoluta, probablemente necesite analizarlo /proc/self/mountinfousted mismo y combinar la información sobre los montajes para el mismo sistema de archivos.

Para obtener más información, consulte mi respuesta a "Enumerar solo montajes de enlace" .

cg909
fuente
Si /proc/self/mountinfopueden contener líneas como 2 1 8:1 /a /b rw - ext4 /dev/sda1 rw,errors=remount-ro, a continuación, Linux sin duda hace mantener un poco de información acerca de montaje de vínculos.
Melab
No. Mira mi segundo ejemplo. Mantiene la información sobre qué sistema de archivos se montó y qué ruta relativa a la raíz del sistema de archivos se montó . Así que para mount --bind /home/melab /mntla línea resultante podría parecerse a cualquiera de los siguientes, dependiendo de cuál de /homey /home/melabes un punto de montaje: 3 1 8:1 /home/melab /mnt rw - ext4 /dev/sda1 rw, 3 1 8:2 /melab /mnt rw - ext4 /dev/sda2 rw,3 1 8:3 / /mnt rw - ext4 /dev/sda3 rw
cg909
Es cierto que algo diferente /en la cuarta columna a menudo indica un montaje de enlace. Pero también podría ser un subvolumen Btrfs.
cg909
¿Se /dev/sda3supone que debe montarse en /home/melab?
Melab
Si. En mi ejemplo usé /dev/sda1as /, /dev/sda2as /homey /dev/sda3as/home/melab
cg909