web-dev-qa-db-fra.com

Pourquoi ne pas monter le respect de l'option en lecture seule pour les supports de liaison?

Sur mon archignon Linux System (Kernel Linux 3.14.2) Les supports de liaison ne respectent pas l'option en lecture seule

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

crée le fichier /mnt/foo. L'entrée pertinente dans /proc/mounts est

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

Les options de montage ne correspondent pas à mes options demandées, mais correspondent à la fois au comportement de lecture/écriture du support de liaison et des options utilisées pour monter à l'origine /dev/sda2 au /

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

Si, cependant, je remonte le montage, alors il respecte l'option en lecture seule

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

et l'entrée pertinente dans /proc/mounts/

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

ressemble à ce que j'avais peut-être attendre (bien que, en vérité, je m'attendrais à voir le chemin complet du répertoire test). L'entrée en /proc/mounts/ pour le mont Orignal de /dev/sda2/ au / est également inchangé et reste lu/écrire

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

Ce comportement et le travail autour ont été connus depuis au moins 2008 et sont documentés dans la page man de mount

Notez que les options de montage du système de fichiers resteront les mêmes que celles du point de montage d'origine et ne peuvent pas être modifiées en passant l'option -o avec --Bind/- RBind. Les options de montage peuvent être modifiées par une commande de remonte séparée

Toutes les distributions ne se comportent pas de la même manière. L'arche semble ne pas manquer de manière silencieuse pour respecter les options tandis que Debian génère un avertissement lorsque la monture de liaison ne reçoit pas la lecture en lecture seule.

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

Il est rapporté que ce comportement était "fixe" dans Debian Lenny et Squeeze Bien qu'il ne semble pas être un solution universelle ni ne fonctionne toujours dans Debian Wheezy. Quelle est la difficulté associée à la mise à montage de liaison respectueuse de la seule option en lecture seule sur le montage initial?

36
StrongBad

Bind Montage est juste ... Eh bien ... une monture de liaison. C'est à dire. Ce n'est pas un nouveau mont. Il suffit de "liens"/"expose"/"considère" un sous-répertoire comme nouveau point de montage. En tant que tel, il ne peut pas modifier les paramètres de montage. C'est pourquoi vous avez des plaintes:

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

Mais comme vous l'avez dit, une monture de liaison normale fonctionne:

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

Et puis un remonte RO fonctionne également:

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

Cependant, ce qui se passe est que vous changez tout le montage et non seulement de ce mont de liaison. Si vous envisagez de consulter/Proc/Supports, vous verrez que la monture de liaison et le mont d'origine changent à la lecture seule:

/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

Donc, ce que vous faites, c'est comme changer la montagne initiale sur un montage en lecture seule et faire une monture de liaison qui sera bien en lecture seule .

Mise à jour 2016-07-20:

Les éléments suivants sont vrais pour 4,5 noyaux, mais pas vrai pour 4,3 noyaux (c'est faux. Voir la mise à jour n ° 2 ci-dessous):

Le noyau a deux drapeaux qui contrôlent la lecture seule:

  • Les MS_READONLY: Indiquant si le mont est en lecture seule
  • Les MNT_READONLY: Indiquer si "l'utilisateur" veut être en lecture seule

Sur un 4,5 noyau, faire un mount -o bind,ro fera effectivement le tour. Par exemple, ceci:

# 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

créera un montage en lecture seule de /tmp/test/a/d à /tmp/test/b, qui sera visible dans /proc/mounts comme:

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

Une vue plus détaillée est visible dans /proc/self/mountinfo, qui prend en compte la vue utilisateur (espace de noms). Les lignes correspondantes seront celles-ci:

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

Où sur la deuxième ligne, vous pouvez voir que cela indique les deux ro (MNT_READONLY) et rw (!MS_READONLY).

Le résultat final est ceci:

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

Mise à jour 2016-07-20 # 2:

Un peu plus de creuser dans ceci montre que le comportement dépend en fait de la version de Libmount qui fait partie de Util-Linux. Soutien à cela a été ajouté avec ce COMMIS et a été publié avec la version 2.27:

 commit 9ac77b8a78452eab0612523d27fee52159f5016a [.____] Auteur: Karel Zak [.____] Date: Mon août 17 11:54:26 2015 +0200 [.____] BIND, RO "[.____] [.____] [ Foo/Bar -o Bind 
 Mont/Bar -o Remonter, Ro, Bind [.____] 
 Ce correctif permet de spécifier "BINDER, RO" et le remontage est fait 
 automatiquement par libmount par montage supplémentaire (2) syscall. Ce n'est pas 
 Atomique bien sûr. 
 
 Signé-by: Karel Zak [.____]

qui fournit également la solution de contournement. Le comportement peut être vu à l'aide de la strace sur un montage plus ancien et plus récent:

Vieille:

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

Nouveau:

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>

Conclusion:

Pour obtenir le résultat souhaité, il faut exécuter deux commandes (comme @ @THOMAS déjà dit):

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

Nouvelles versions de montage (Util-Linux> = 2.27) Faites-le automatiquement quand on fonctionne

mount SRC DST -o bind,ro
23
V13

La solution appropriée est vraiment de la monter deux fois. Sur la ligne de commande:

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

Dans /etc/fstab:

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

Le manuel (man mount) le dit de cette façon:

   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
9
Thomas