GNU/Linux >> Znalost Linux >  >> Linux

Proč připojení nerespektuje možnost pouze pro čtení pro připojení připojení?

Bind mount je prostě... no... poutač. Tj. není to nový držák. Pouze "linkuje"/"vystavuje"/"považuje" podadresář za nový přípojný bod. Jako takový nemůže měnit parametry připojení. To je důvod, proč dostáváte stížnosti:

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

Ale jak jste řekl, normální připojení k připojení funguje:

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

A pak také funguje přepojení ro:

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

Stane se však, že měníte celé připojení a ne pouze toto připojení. Pokud se podíváte na /proc/mounts, uvidíte, že připojení vazby i původní připojení se změní na pouze pro čtení:

/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

Takže to, co děláte, je jako změnit počáteční připojení na připojení pouze pro čtení a pak provedení připojení k připojení, které bude samozřejmě pouze pro čtení.

AKTUALIZACE 20.07.2016:

Následující platí pro jádra 4.5, ale neplatí pro jádra 4.3 (To je špatně. Viz aktualizace č. 2 níže):

Jádro má dva příznaky, které řídí pouze pro čtení:

  • MS_READONLY :Označuje, zda je připojení pouze pro čtení
  • MNT_READONLY :Označení, zda jej „uživatel“ chce pouze pro čtení

Na jádře 4.5 proveďte mount -o bind,ro skutečně udělá ten trik. Například toto:

# 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

vytvoří připojení vazby pouze pro čtení /tmp/test/a/d/tmp/test/b , který bude viditelný v /proc/mounts jako:

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

Podrobnější pohled je viditelný v /proc/self/mountinfo , který bere v úvahu pohled uživatele (jmenný prostor). Příslušné řádky budou tyto:

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

Kde na druhém řádku vidíte, že je napsáno jak ro (MNT_READONLY ) a rw (!MS_READONLY ).

Konečný výsledek je tento:

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

AKTUALIZACE 2016-07-20 #2:

Trochu podrobnější zkoumání ukazuje, že chování ve skutečnosti závisí na verzi libmount, která je součástí util-linux. Podpora pro toto byla přidána s tímto potvrzením a byla vydána s verzí 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 

který také poskytuje řešení. Chování lze vidět pomocí strace na starším a novějším připojení:

Starý:

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

Nové:

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>

Závěr:

K dosažení požadovaného výsledku je třeba spustit dva příkazy (jak již řekl @Thomas):

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

Novější verze mount (util-linux>=2.27) to dělají automaticky při spuštění.

mount SRC DST -o bind,ro

Správným řešením je skutečně připojit jej dvakrát. Na příkazovém řádku:

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

V /etc/fstab :

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

Příručka (man mount ) to uvádí takto:

   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. Proč je deskriptor souboru otevřen a přečten pouze jednou?

  2. Získat procento využití pro Mount Point?

  3. Proč je cPanel nejlepším řešením pro návrháře webových stránek

  1. Bind mounts v Linuxu

  2. K čemu slouží možnost „soname“ pro vytváření sdílených knihoven?

  3. Proč je obyčejné dm-crypt doporučeno pouze odborníkům?

  1. Vypsat pouze připojení připojení

  2. Proč lidé s Linuxem vždy říkají, že si přečti manuál?

  3. Proč je moje připojení připojení viditelné mimo jeho jmenný prostor připojení?