Conclusión:

Conclusión:

En mi sistema Arch Linux (Linux Kernel 3.14.2), los montajes vinculados no respetan la opción de solo lectura

# mkdir test
# mount --bind -o ro test/ /mnt
# touch /mnt/foo

crea el archivo /mnt/foo. La entrada relevante /proc/mountses

/dev/sda2 /mnt ext4 rw,noatime,data=ordered 0 0

Las opciones de montaje no coinciden con las opciones solicitadas, pero coinciden tanto con el comportamiento de lectura/escritura del montaje de enlace como con las opciones utilizadas para montar /dev/sda2originalmente/

/dev/sda2 / ext4 rw,noatime,data=ordered 0 0

Sin embargo, si vuelvo a montar el soporte, se respeta la opción de solo lectura.

# mount --bind -o remount,ro test/ /mnt
# touch /mnt/bar
touch: cannot touch ‘/mnt/bar’: Read-only file system

y la entrada correspondiente en/proc/mounts/

/dev/sda2 /mnt ext4 ro,relatime,data=ordered 0 0

se parece a lo que podría esperar (aunque en realidad esperaría ver la ruta completa del testdirectorio). La entrada /proc/mounts/para el montaje original de /dev/sda2/on /tampoco cambia y permanece en lectura/escritura.

/dev/sda2 / ext4 rw,noatime,data=ordered 0 0

Este comportamiento y la solución se conocen desde al menos2008y están documentados en la página de manual demount

Tenga en cuenta que las opciones de montaje del sistema de archivos seguirán siendo las mismas que las del punto de montaje original y no se pueden cambiar pasando la opción -o junto con --bind/--rbind. Las opciones de montaje se pueden cambiar mediante un comando de montaje independiente.

No todas las distribuciones se comportan igual. Arch parece no respetar silenciosamente las opciones, mientras que Debian genera una advertencia cuando el montaje del enlace no se monta en modo de solo lectura.

mount: warning: /mnt seems to be mounted read-write.

Hay informes de que este comportamiento fue "solucionado" en DebianLenny y aprietaaunque no parece ser unarreglo universalni sigue funcionando en Debian Wheezy. ¿Cuál es la dificultad asociada con hacer que el montaje vinculado respete la opción de solo lectura en el montaje inicial?

Respuesta1

La montura vinculante es simplemente... bueno... una montura vinculante. Es decir, no es una montura nueva. Simplemente "vincula"/"expone"/"considera" un subdirectorio como un nuevo punto de montaje. Como tal, no puede alterar los parámetros de montaje. Por eso recibes 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 enlace normal funciona:

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

Y luego un remontaje ro también funciona:

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

Sin embargo, lo que sucede es que estás cambiando toda la montura y no solo esta montura vinculante. Si echas un vistazo a /proc/mounts verás 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 sólo lectura yentonceshaciendo un montaje de enlace que, por supuesto, será de solo lectura.

ACTUALIZACIÓN 2016-07-20:

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

El kernel tiene dos indicadores que controlan el modo de solo lectura:

  • The MS_READONLY: indica si el montaje es de solo lectura
  • The MNT_READONLY: indica si el "usuario" quiere que sea de solo lectura

En un kernel 4.5, hacer a mount -o bind,rorealmente funcionará. 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/dto /tmp/test/b, que será visible /proc/mountscomo:

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

En la segunda línea, puede ver que dice tanto ro( MNT_READONLY) como 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:

Un poco más de investigación sobre esto muestra que el comportamiento, de hecho, depende de la versión de libmount que es parte de util-linux. Se agregó soporte para esto con estocomprometersey fue lanzado con la versión 2.27:

confirmar 9ac77b8a78452eab0612523d27fee52159f5016a
Autor: Karel Zak
Fecha: lunes 17 de agosto 11:54:26 2015 +0200

    libmount: agrega soporte para "bind,ro"

    Ahora es necesario usar dos llamadas mount(8) para crear un archivo de sólo lectura.
    montar:

      montar /foo /bar -o enlazar
      montar /bar -o remontar,ro,enlazar

    Este parche permite especificar "bind,ro" y se realiza el remontaje.
    automáticamente por libmount mediante syscall adicional mount(2). Que no es
    atómico por supuesto.

    Firmado por: Karel Zak

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

Viejo:

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, es necesario 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

Respuesta2

La solución adecuada es 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

Respuesta3

Lo preguntas desde la perspectiva de la mount(8)línea de comando (que es aceptable en este sitio). Ese comando se ha analizado en otras respuestas y, en algunos casos, abstrae la segunda mount(2)llamada al sistema necesaria.

Pero, ¿por qué se necesita la segunda llamada al sistema? ¿Por qué una sola mount(2)llamada no puede crear el montaje de enlace de solo lectura?

Elmount(2)página de manualexplica que hay, como otros han señalado,dos conjuntosde banderas que se establecen:

  • Las banderas del sistema de archivos subyacente
  • Las banderas del punto de montaje de VFS

Dice:

Desde Linux 2.6.16, MS_RDONLYse puede configurar o borrar por punto de montaje, así como en el sistema de archivos subyacente. Solo se podrá escribir en el sistema de archivos montado si ni el sistema de archivos ni el punto de montaje están marcados como de solo lectura.

Y respecto a MS_REMOUNT:

Desde Linux 2.6.26, este indicador se puede usar para MS_BINDmodificar solo los indicadores por punto de montaje. Esto es particularmente útil para configurar o borrar el indicador de "solo lectura" en un punto de montaje sin cambiar el sistema de archivos subyacente. Especificando mountflags como:

      MS_REMOUNT | MS_BIND | MS_RDONLY

hará que el acceso a través de este punto de montaje sea de solo lectura, sin afectar otros puntos de montaje.

Creo que el problema surgió cuando se introdujeron por primera vez los montajes enlazados:

Si mountflags incluye MS_BIND(disponible desde Linux 2.4), realice un montaje vinculado. ... Los bits restantes en el argumento mountflags también se ignoran, con la excepción de MS_REC. (El montaje de enlace tiene las mismas opciones de montaje que el punto de montaje subyacente).

Parece que, en lugar de utilizar MS_BIND | MS_REMOUNTcomo señal para configurar solo los indicadores VFS, podrían haber elegido aceptar (y aceptar) MS_RDONLYjunto con el inicial MS_BINDy aplicarlo al punto de montaje.

Debido a la semántica algo extraña de la mount(2)llamada al sistema:

  • La primera llamada crea el montaje de enlace y todos los demás indicadores se ignoran
  • La segunda llamada (con remontar) establece elpunto de montajebanderas a solo lectura

información relacionada