GNU/Linux >> Tutoriales Linux >  >> Linux

¿Por qué el montaje no respeta la opción de solo lectura para los montajes de enlace?

Bind Mount es solo... bueno... un Bind Mount. Es decir. no es una montura nueva. Simplemente "enlaza"/"expone"/"considera" un subdirectorio como un nuevo punto de montaje. Como tal, no puede alterar los parámetros de montaje. Por eso recibe quejas:

# mount /mnt/1/lala /mnt/2 -o bind,ro
mount: warning: /mnt/2 seems to be mounted read-write.

Pero como dijiste, un montaje de vinculación normal funciona:

# mount /mnt/1/lala /mnt/2 -o bind

Y luego un montaje de ro también funciona:

# mount /mnt/1/lala /mnt/2 -o bind,remount,ro 

Sin embargo, lo que sucede es que está cambiando todo el montaje y no solo este enlace. Si echa un vistazo a /proc/mounts, verá que tanto el montaje enlazado como el montaje original cambian a solo lectura:

/dev/loop0 /mnt/1 ext2 ro,relatime,errors=continue,user_xattr,acl 0 0
/dev/loop0 /mnt/2 ext2 ro,relatime,errors=continue,user_xattr,acl 0 0

Entonces, lo que estás haciendo es como cambiar el montaje inicial a un montaje de solo lectura y luego haciendo un montaje de vinculación que, por supuesto, será de solo lectura.

ACTUALIZACIÓN 2016-07-20:

Lo siguiente es cierto para los kernels 4.5, pero no para los kernels 4.3 (esto es incorrecto. Consulte la actualización n.° 2 a continuación):

El kernel tiene dos banderas que controlan solo lectura:

  • El MS_READONLY :indica si el montaje es de solo lectura
  • El MNT_READONLY :Indica si el "usuario" lo quiere de solo lectura

En un kernel 4.5, haciendo un mount -o bind,ro realmente hará el truco. Por ejemplo, esto:

# mkdir /tmp/test
# mkdir /tmp/test/a /tmp/test/b
# mount -t tmpfs none /tmp/test/a
# mkdir /tmp/test/a/d
# mount -o bind,ro /tmp/test/a/d /tmp/test/b

creará un montaje de enlace de solo lectura de /tmp/test/a/d a /tmp/test/b , que será visible en /proc/mounts como:

none /tmp/test/a tmpfs rw,relatime 0 0
none /tmp/test/b tmpfs ro,relatime 0 0

Se puede ver una vista más detallada en /proc/self/mountinfo , que tiene en cuenta la vista del usuario (espacio de nombres). Las líneas relevantes serán estas:

363 74 0:49 / /tmp/test/a rw,relatime shared:273 - tmpfs none rw
368 74 0:49 /d /tmp/test/b ro,relatime shared:273 - tmpfs none rw

Donde en la segunda línea, puede ver que dice ambos ro (MNT_READONLY ) y rw (!MS_READONLY ).

El resultado final es este:

# echo a > /tmp/test/a/d/f
# echo a > /tmp/test/b/f
-su: /tmp/test/b/f: Read-only file system

ACTUALIZACIÓN 2016-07-20 #2:

Profundizar un poco más en esto muestra que el comportamiento, de hecho, depende de la versión de libmount que forma parte de util-linux. Se agregó soporte para esto con este compromiso y se lanzó con la versión 2.27:

commit 9ac77b8a78452eab0612523d27fee52159f5016a
Author: Karel Zak 
Date:   Mon Aug 17 11:54:26 2015 +0200

    libmount: add support for "bind,ro"

    Now it's necessary t use two mount(8) calls to create a read-only
    mount:

      mount /foo /bar -o bind
      mount /bar -o remount,ro,bind

    This patch allows to specify "bind,ro" and the remount is done
    automatically by libmount by additional mount(2) syscall. It's not
    atomic of course.

    Signed-off-by: Karel Zak 

que también proporciona la solución. El comportamiento se puede ver usando strace en una montura más antigua y una más nueva:

Antiguo:

mount("/tmp/test/a/d", "/tmp/test/b", 0x222e240, MS_MGC_VAL|MS_RDONLY|MS_BIND, NULL) = 0 <0.000681>

Nuevo:

mount("/tmp/test/a/d", "/tmp/test/b", 0x1a8ee90, MS_MGC_VAL|MS_RDONLY|MS_BIND, NULL) = 0 <0.011492>
mount("none", "/tmp/test/b", NULL, MS_RDONLY|MS_REMOUNT|MS_BIND, NULL) = 0 <0.006281>

Conclusión:

Para lograr el resultado deseado, se deben ejecutar dos comandos (como ya dijo @Thomas):

mount SRC DST -o bind
mount DST -o remount,ro,bind

Las versiones más nuevas de mount (util-linux>=2.27) hacen esto automáticamente cuando se ejecuta

mount SRC DST -o bind,ro

La solución adecuada es realmente montarlo dos veces. En la línea de comando:

mount -t none -o bind /source/dir /destination/dir
mount -t none -o bind,remount,ro /source/dir /destination/dir

En /etc/fstab :

/source/dir            /destination/dir    none  bind            0 0
/source/dir            /destination/dir    none  remount,bind,ro 0 0

El manual (man mount ) lo dice así:

   The bind mounts.
          Since Linux 2.4.0 it is possible to remount part of the file hierarchy somewhere else. The call is
                 mount --bind olddir newdir
   [...]
          Note that the filesystem mount options will remain the same as those on the original mount point, and cannot be changed  by  passing  the  -o  option
          along with --bind/--rbind. The mount options can be changed by a separate remount command, for example:
          .
                 mount --bind olddir newdir
                 mount -o remount,ro newdir
          .
          Note  that  behavior  of  the remount operation depends on the /etc/mtab file. The first command stores the 'bind' flag to the /etc/mtab file and the
          second command reads the flag from the file.  If you have a system without the /etc/mtab file or if you explicitly define source and target  for  the
          remount command (then mount(8) does not read /etc/mtab), then you have to use bind flag (or option) for the remount command too. For example:
          .
                 mount --bind olddir newdir
                 mount -o remount,ro,bind olddir newdir

Linux
  1. ¿Por qué el documento principal Shell Here no funciona para el subcomando en Dash pero Bash funciona?

  2. Por qué cPanel es la mejor solución para diseñadores de sitios web

  3. ¿Por qué xargs -L produce el formato correcto, mientras que xargs -n no?

  4. ¿Por qué bifurcar mi proceso hace que el archivo se lea infinitamente?

  5. Para mostrar la ruta de origen del montaje vinculante para el montaje después de v2.25.2

Por qué usar el escritorio Pantheon para Linux Elementary OS

Vincular montajes en Linux

¿Para qué sirve la opción 'soname' para crear bibliotecas compartidas?

Listar solo montajes enlazados

¿Por qué mi montaje de enlace está visible fuera de su espacio de nombres de montaje?

Haga que el archivo sea de solo lectura en Linux, incluso para root