GNU/Linux >> Belajar Linux >  >> Linux

Mengapa mount tidak menghargai opsi read only untuk bind mount?

Bind mount hanyalah... yah... sebuah bind mount. Yaitu. itu bukan tunggangan baru. Itu hanya "tautan"/"mengekspos"/"menganggap" subdirektori sebagai titik pemasangan baru. Karena itu tidak dapat mengubah parameter pemasangan. Itu sebabnya Anda menerima keluhan:

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

Tapi seperti yang Anda katakan, bind mount yang normal berfungsi:

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

Dan kemudian ro remount juga berfungsi:

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

Namun yang terjadi adalah Anda mengubah seluruh mount dan bukan hanya binding mount ini. Jika Anda melihat /proc/mounts, Anda akan melihat bahwa bind mount dan mount asli berubah menjadi read-only:

/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

Jadi yang Anda lakukan adalah seperti mengubah pemasangan awal menjadi pemasangan hanya-baca dan lalu melakukan bind mount yang tentu saja hanya bisa dibaca.

PEMBARUAN 20-07-2016:

Yang berikut ini benar untuk kernel 4.5, tetapi tidak benar untuk kernel 4.3 (Ini salah. Lihat pembaruan #2 di bawah):

Kernel memiliki dua flag yang mengontrol read-only:

  • MS_READONLY :Menunjukkan apakah mount bersifat read-only
  • MNT_READONLY :Menunjukkan apakah "pengguna" menginginkannya hanya-baca

Pada kernel 4.5, lakukan mount -o bind,ro benar-benar akan melakukan trik. Misalnya, ini:

# 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

akan membuat pengikatan read-only dari /tmp/test/a/d ke /tmp/test/b , yang akan terlihat di /proc/mounts sebagai:

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

Tampilan yang lebih detail terlihat di /proc/self/mountinfo , yang mempertimbangkan tampilan pengguna (namespace). Baris yang relevan adalah ini:

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

Di mana pada baris kedua, Anda dapat melihat bahwa keduanya bertuliskan ro (MNT_READONLY ) dan rw (!MS_READONLY ).

Hasil akhirnya adalah ini:

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

PEMBARUAN 20-07-2016 #2:

Sedikit menggali lebih dalam menunjukkan bahwa perilaku sebenarnya tergantung pada versi libmount yang merupakan bagian dari util-linux. Dukungan untuk ini ditambahkan dengan komit ini dan dirilis dengan versi 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 

yang juga menyediakan solusinya. Perilaku tersebut dapat dilihat menggunakan strace pada mount yang lebih lama dan lebih baru:

Lama:

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

Baru:

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>

Kesimpulan:

Untuk mencapai hasil yang diinginkan, seseorang perlu menjalankan dua perintah (seperti yang sudah dikatakan @Thomas):

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

Versi mount yang lebih baru (util-linux>=2.27) melakukan ini secara otomatis saat dijalankan

mount SRC DST -o bind,ro

Solusi yang tepat adalah memasangnya dua kali. Pada baris perintah:

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

Di /etc/fstab :

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

Manual (man mount ) menyatakan seperti itu:

   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. Mengapa Dokumen Induk Shell Di Sini Tidak Berfungsi Untuk Sub-perintah Di Dash Tapi Bash Bekerja?

  2. Bind mount di Linux

  3. Mengapa xargs -L menghasilkan format yang benar, sedangkan xargs -n tidak?

  1. Untuk menampilkan jalur sumber mount pengikat untuk mount setelah v2.25.2

  2. Mengapa orang Linux selalu mengatakan untuk membaca manual?

  3. Mengapa bind mount saya terlihat di luar mount namespace-nya?

  1. Mengapa File Descriptor Dibuka Dan Hanya Dibaca Sekali?

  2. Dapatkan Persentase Penggunaan Untuk Sebuah Mount Point?

  3. Setel opsi pemasangan untuk titik pemasangan yang diberikan dengan kemungkinan