GNU/Linux >> Linux の 問題 >  >> Linux

マウントがバインド マウントの読み取り専用オプションを尊重しないのはなぜですか?

バインド マウントは、まさしく... バインド マウントです。つまり新しいマウントではありません。サブディレクトリを新しいマウントポイントとして「リンク」/「公開」/「検討」するだけです。そのため、マウント パラメータを変更することはできません。そのため、苦情が寄せられています:

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

しかし、あなたが言ったように、通常のバインド マウントは機能します:

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

そして、ro 再マウントも機能します:

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

ただし、このバインド マウントだけでなく、マウント全体を変更することになります。 /proc/mounts を見ると、バインド マウントと元のマウントの両方が読み取り専用に変更されていることがわかります。

/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

つまり、最初のマウントを読み取り専用マウントに変更して、その後マウントするようなものです。 もちろん読み取り専用になるバインド マウントを実行します。

2016 年 7 月 20 日更新:

以下は 4.5 カーネルには当てはまりますが、4.3 カーネルには当てはまりません (これは誤りです。以下の更新 #2 を参照してください):

カーネルには、読み取り専用を制御する 2 つのフラグがあります:

  • MS_READONLY :マウントが読み取り専用かどうかを示す
  • MNT_READONLY :「ユーザー」が読み取り専用にするかどうかを示す

4.5 カーネルで mount -o bind,ro を実行 実際にトリックを行います。たとえば、これ:

# 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

/tmp/test/a/d の読み取り専用バインド マウントを作成します /tmp/test/b へ 、これは /proc/mounts で表示されます として:

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

より詳細なビューは /proc/self/mountinfo に表示されます 、ユーザー ビュー (名前空間) を考慮します。関連する行は次のとおりです:

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

2 行目のどこに ro と書かれていることがわかります。 (MNT_READONLY ) と rw (!MS_READONLY ).

最終結果は次のとおりです:

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

2016 年 7 月 20 日更新 #2:

これをもう少し掘り下げると、実際の動作は util-linux の一部である libmount のバージョンに依存することがわかります。このサポートはこのコミットで追加され、バージョン 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 

これは回避策も提供します。この動作は、古いマウントと新しいマウントで strace を使用して確認できます:

古い:

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

新規:

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>

結論:

望ましい結果を得るには、2 つのコマンドを実行する必要があります (@Thomas が既に述べたように):

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

新しいバージョンのマウント (util-linux>=2.27) は、実行時にこれを自動的に行います

mount SRC DST -o bind,ro

適切な解決策は、実際には 2 回マウントすることです。コマンド ラインで:

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

/etc/fstab で :

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

マニュアル (man mount ) は次のように述べています:

   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. マウントポイントの使用率を取得しますか?

  2. Linuxでマウントをバインドする

  3. 共有ライブラリを構築するための「soname」オプションは何ですか?

  1. プロセスをフォークすると、ファイルが無限に読み取られるのはなぜですか

  2. v2.25.2 以降のマウントのバインド マウント ソース パスを表示するには

  3. バインド マウントのみを一覧表示する

  1. ヒアドキュメントの親シェルがダッシュのサブコマンドでは機能しないのに、Bashは機能するのはなぜですか?

  2. ファイル記述子が開かれ、一度だけ読み取られるのはなぜですか?

  3. root であっても Linux でファイルを読み取り専用にする